/*
 * Copyright 2025 OmniOne.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.omnione.did.sdk.core.api;

import android.content.Context;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.omnione.did.sdk.core.keymanager.datamodel.DetailKeyInfo;
import org.omnione.did.sdk.core.zkp.datamodel.ZKPInfo;
import org.omnione.did.sdk.datamodel.util.GsonWrapper;
import org.omnione.did.sdk.datamodel.zkp.AvailableReferent;
import org.omnione.did.sdk.datamodel.zkp.Credential;
import org.omnione.did.sdk.datamodel.zkp.CredentialDefinition;
import org.omnione.did.sdk.datamodel.zkp.CredentialOffer;
import org.omnione.did.sdk.datamodel.zkp.CredentialSchema;
import org.omnione.did.sdk.datamodel.zkp.Proof;
import org.omnione.did.sdk.datamodel.zkp.ProofRequest;
import org.omnione.did.sdk.datamodel.zkp.UserReferent;
import org.omnione.did.sdk.datamodel.zkp.CredentialRequestContainer;
import org.omnione.did.sdk.wallet.walletservice.config.Constants;
import org.omnione.did.sdk.wallet.walletservice.logger.WalletLogger;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Instrumented test, which will execute on an Android device.
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
@RunWith(AndroidJUnit4.class)
public class ZKPManagerTest {
    private ZKPManager<ZKPInfo> zkpManager;
    private Context appContext;

    private CredentialDefinition credentiaDefinition;
    private CredentialSchema credentialSchema;

    private CredentialOffer credentialOffer;

    private CredentialRequestContainer requestCredentialBuilder;
    private Credential credential;

    private ProofRequest proofRequest;

    private Proof proof;

    @Before
    public void setUp() throws Exception {

        String credentialSchemaDummyStr = """
                {
                    "id": "did:omn:NcYxiDXkpYi6ov5FcYDi1e:2:mdl:1.0",
                    "name": "mdl",
                    "version": "1.0",
                    "attrNames": [
                      "zkpsex",
                      "zkpbirth",
                      "zkpasort",
                      "zkpaddr"
                    ],
                    "tag": "Tag1"
                 }
                """;

        String credentialDefinitionDummyStr = """
                {
                   "id": "did:omn:NcYxiDXkpYi6ov5FcYDi1e:3:CL:did:omn:NcYxiDXkpYi6ov5FcYDi1e:2:mdl:1.0:Tag1",
                   "schemaId": "did:omn:NcYxiDXkpYi6ov5FcYDi1e:2:mdl:1.0",
                   "ver": "1.0",
                   "type": "CL",
                   "value": {
                     "primary": {
                       "n": "98303800829146496294260160277064268331997919907118759390341500977350328166231517842000775091885887150173587119204384338228587724360025337049924757520313312201967020621759572051207343682524231935224405489201055290440185974163176510090104878576328701169995084378244199652705467063808794161203659959161149007560127132880037670744886830245515761491866073613220925105572633838346259499516370003770635360926827954402726520906767008144937661365310505092955511528775052544241834421613190566785085445456937701280326372707495576721065482434721663368327906510789615533263108653864638625962089969817420000555300172786602890031221",
                       "z": "72476003402007365559845556565928748634806635139915883752613978409390905473126308272088551665751629557527257026090780882691565781493322875659930119643976149862378328821967019926482197108791091154851790913335186839467689882726608570719356393427228546437409130994394865806550695073573932358383734770013893947715744418713218523513852217777745393365867228181847718884555751338270184175861561563259256932546644962128365319668849633778829063325365704573290067047449396450683423407963221126024796067021850646141878891788651428388285824121668669515579146276588320968622193946126211400858500602056039724125800562011256035753131",
                       "s": "42314428938118651571186826115134779703483860703086624763940907279828698343295258869302936902207120747882781851312755192816862314522225460396884842099213493974195517824496394650177103662754174830470703442972131971001425153355112726092080168793819667247586882921414873593569350032645531140544160791135054500233885330752639300244506870615490491828118515865133108172271535798636685236616016643517056751913538825367987339304843930223652791588424587962670061239280811316528119994322519407542959050448909523629103578296396202312034666996580473802018483894901318690336198309682137367349639995672383323486161882045531431553620",
                       "r": {
                         "zkpsex": "55856258491718600183578747725394577058175299012235450980870451124420472847769638939899699948204084420040721298519195180280673566380743966286459415516028117435807493128391803773613043738394487412468071691445691341287159426511963376901192765305925646648979484805990584368413304006578086990644976452873172736950919175279445194223943551126543021913515294990653772406633036032048648323610201574970392698658520618413654053732744486131774566361736181233648075067983084577473701664336446529213875081372113519997764037899535174364245030758097848781320690469733758039606208126901257777005972500335973326304021028990789319396744",
                         "zkpbirth": "85158537279594543764612067545704901307148704299981131117146381651501626072046716431622294925466055909084083647564884189504115360484733128050786697623696710736714894960320633887890104711428317745706382587483367061121581674536862526553645110134940963924604687568380664520137801818425009523997788989807204669993469111525480761242055035971492463111588752799646426548900412229706060655841529691825945291885918516843242675029476568439703489225489724553234561672936978261046206520951690989612305432928729802963526578055910897993472817750618105574342583031545253811648810639317146140102769214856112071958560952275781689335970",
                         "zkpasort": "89401798810728642732230531762237007436002334565140227727256108252680001327430770577873910420276923690188395853544051661927904675924590031232736166294741963827306028420805048827461739783631673329330967429227849294054906937660202901106342099487486411462201450652392337823529796764162060156613664205251085575226636654517485697948914392269172615433301521976466801480377708600322423849655346773206376775404106401426521576636176920892891201409748848783952182138515483726978624167443614284828248273972145544143281442162414348088477470101210087253986634288871428442153997368255901639691042008086572996019123464650955374767427",
                         "zkpaddr": "35327816871925246457721034006978468971932984388376049510237420758127112959035598105950451770955506735540268163106082394818652640926129408835988647780400225208831474167172922996714094345348565773735560074388214122807415005540677918812208834883396018769027464935740876851827837213501025012150821764283900887761863359509607744595958328240633065639316625220399598050170321690347840521204331005821111041369147902690802227593991228382228241872196008977815927452648847142802478986408359114513555260611768288556084180393725205929255346560469954314749844008428970323964715139638524949099676411371948640827019656239031403940833",
                         "masterSecret": "56161441273518594236416674958351166165214447709131134259512183342535559199924445226233410565229462633126465531315201555453851525043690648655490945734180933618215162682623265380607993141742513649610961100646438797828535910504683212056945848781833563077473679901857119331342394660587471432027717640252212702875041598397252805144530744909665092967623046127023432226353053122729743510992501150766658352716500326624678473078051806151586902341089935567032624396633791375082246850091796425578916855672382877404454977532275062377857183992551234056929376807696632864940126934403300965142577553118509441802377884210429312789022"
                       },
                       "rctxt": "29512332269993461347297004284409919060308131072241645818239226076877674579759450679700905457955935349745557470984805228939597955504107392620397861039870489396452707288706421356484420055349276383356938674378397417771664070170380361139154405931036516403936062384562334149738813184413862029453007307254973649503982300442428413755779397598414947962839743927857393201171138047075946745614904219348190203091348796605450772728266115963448657795732772775239200766325854934037701620727713695286950430822767720019956190139220981022648090270613554560237275048644354051929601119033748360494100929666087560754924146656630777429115"
                     }
                   },
                   "tag": "Tag1"
                 }
                """;

        String credentialOfferDummyStr = """
                {
                   "nonce": "1068995366822249097155600",
                   "schemaId": "did:omn:NcYxiDXkpYi6ov5FcYDi1e:2:mdl:1.0",
                   "credDefId": "did:omn:NcYxiDXkpYi6ov5FcYDi1e:3:CL:did:omn:NcYxiDXkpYi6ov5FcYDi1e:2:mdl:1.0:Tag1",
                   "keyCorrectnessProof": {
                     "c": "72901940107821403108172386416242877597589945189240875901204927790716512840875",
                     "xzCap": "1411558388033389597075405334556637104048209868032249897787189266029904589968309498691685105104879697994232560581977708166152287174259189217345701003875840409628091506021238002932637724361546856491692965944843193022913295707040071721327683402423513205167459729727217524469859203349361191183950945720818562115457457711901334275926228330641984095743249911903231578050290012621790494284952986597483688471563208834983135591045210242200778746357356713118003656991303348392754358344145764394446320163913007771819903192772727861081494526129371105001032817898266483191782552411767943950308711528357764996664071192512793529328957629514628302658184543172499298330404916782353844397515865736796640554420206",
                     "xrCap": {
                       "zkpsex": "1486186029768890363363791872544170828991330718315979352704558320864232552948561150199808815897261826881165428533045516627340792965230681042255818030784166263897111230989206973120997418257132897786247066673391587020759755070723696537101756800963238226923670314064004665441045730150603050459137181687587234683939582080952806369446970441415846185046359156846108732976044253194236524723648704336062234754846186216985156812978480119784900349066768745107673540540804069883467368971287753091487384863261748139001200985250807922865151460524534945859669670020474357080675543898123465855955208263382622087519192620799651467253085410172980284194789608776849530850552172251024711291774435661251280624004215",
                       "zkpbirth": "51393859289519447309267524496920566159166399233233930986853855319233463125751158891581396989705886969721385051348787903954431155034645209083261437448386340842437267170080559589611006575302645045815421300471114895067614820593992841428514782092780261562312495355412998404203812425310922138977042611649017857689936782460480458323327986051910020331914737777501652853699783742231337758051152227126940441173063057361476779450122413377374460037362561762414902287980072045559032350197640715818949823909791799871460391649454794160834799770346081229672994988099626556387854079464016909837250798490784060805614268925480080956788841638390219615268200473271818342136791661203331610094696676117653396574817",
                       "zkpasort": "172050142319919596421923249616694997183969967128874603633857577373166609016118680196197809458977918603133773989005721688942231091836969102339842467939543285765903027042207845566125155414298043670726527960761307866478904080401457904102049908672351477047788281558734743196008820983069137510836228311530786829413261598470482368908944913282297207153145623456543115847433512767038976019713610325862405271617030609070760902723992630070827393381119190375482965063807330532748508044494089069962047993166702971456576209450828003042106505922476524970008031325269855757511511736232284731462031636161624268512918465714043383036798039936938060934307594588795740920551916314782635995816558842521266593624526",
                       "zkpaddr": "1099429362256214352584674986041322943455831836739532404915477021943197795058181394885573782306702921845626297606931175007060905513411605666952833921792715375757955133954621322609909124372423242524087887357648741598902908196407782925119314245492663480600590253317410896117359070874055466671781405755668802003954684717817693783051728361542969859625766783384945279861898885925812151316030694939276786607759656093648397240269173345592350896501864305590787077923084022377174288180855002030478924391726826894368312707674606184440153263645753409658303740286002261178923736182938581629324691831483193601881128084793868275249143801558170692119087254732056324279001093542941600008295212992764094495495981",
                       "masterSecret": "1471209351752317903450284208024258720257907973005550042953616639025797077346266962267222015913870379327732878388165128934543455051377585508131647857687850910791614195213650911723638622033851455378168605783487354643656322849535669807141070454201034576341501079937526225925190263815059501256611860209900689584012672681692543911062345738598965928764795294389155783816676959197740737420568647898132731994646221215773810889197286208355672307331295310224051953380977684697953736874623399297936803548149861250029956654820483141765828765783929736319238222296030043111512621317398245531951996044604998757907975854061413706257753442274565863646498322048036916097637708994256845857735073310836063516453631"
                     }
                   }
                 }
                """;

        WalletLogger.getInstance().enable();
        appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();

        credentialSchema = GsonWrapper.getGson().fromJson(credentialSchemaDummyStr, CredentialSchema.class);
        credentiaDefinition = GsonWrapper.getGson().fromJson(credentialDefinitionDummyStr, CredentialDefinition.class);
        credentialOffer = GsonWrapper.getGson().fromJson(credentialOfferDummyStr, CredentialOffer.class);

//        zkpManager = new ZKPManager<>(Constants.WALLET_HOLDER, appContext);
    }

    @Test
    public void zkpIssueAndVerifyCredential() throws Exception {
//        createRequestCredentialTest();
//        createCredentialTest();
//        createProofAndVerify();
    }

    private void createProofAndVerify() throws Exception {
        String proofRequestDummyStr = """
                {
                  "name": "mdl",
                  "version": "1.0",
                  "nonce": "1068995366822249097155600",
                  "requestedAttributes": {
                    "attributeReferent1": {
                      "name": "zkpsex",
                      "restrictions": [
                        {
                          "credDefId": "did:omn:NcYxiDXkpYi6ov5FcYDi1e:3:CL:did:omn:NcYxiDXkpYi6ov5FcYDi1e:2:mdl:1.0:Tag1"
                        }
                      ]
                    },
                    "attributeReferent2": {
                      "name": "zkpasort",
                      "restrictions": [
                        {
                          "credDefId": "did:omn:NcYxiDXkpYi6ov5FcYDi1e:3:CL:did:omn:NcYxiDXkpYi6ov5FcYDi1e:2:mdl:1.0:Tag1"
                        }
                      ]
                    },
                    "attributeReferent3": {
                      "name": "zkpaddr",
                      "restrictions": [
                        {
                          "credDefId": "did:omn:NcYxiDXkpYi6ov5FcYDi1e:3:CL:did:omn:NcYxiDXkpYi6ov5FcYDi1e:2:mdl:1.0:Tag1"
                        }
                      ]
                    }
                  },
                  "requestedPredicates": {
                    "predicateReferent1": {
                      "name": "zkpbirth",
                      "pType": "LE",
                      "pValue": 20250103,
                      "restrictions": [
                        {
                          "credDefId": "did:omn:NcYxiDXkpYi6ov5FcYDi1e:3:CL:did:omn:NcYxiDXkpYi6ov5FcYDi1e:2:mdl:1.0:Tag1"
                        }
                      ]
                    }
                  },
                  "nonRevoked": {
                    "from": "",
                    "to": "1744596804276"
                  }
                }
                """;

        proofRequest = GsonWrapper.getGson().fromJson(proofRequestDummyStr, ProofRequest.class);

//        zkpManager.searchCredentials(proofRequest);
        String availableReferentDummyStr = """
                {
                  "selfAttrReferent": {},
                  "attrReferent": {
                    "attributeReferent3": {
                      "name": "zkpaddr",
                      "checkRevealed": true,
                      "referent": [
                        {
                          "raw": "seoul",
                          "credId": "cf0867d1-02aa-4bcf-a7bc-be7eb5eae19e",
                          "credDefId": "did:omn:NcYxiDXkpYi6ov5FcYDi1e:3:CL:did:omn:NcYxiDXkpYi6ov5FcYDi1e:2:mdl:1.0:Tag1"
                        }
                      ]
                    },
                    "attributeReferent2": {
                      "name": "zkpasort",
                      "checkRevealed": true,
                      "referent": [
                        {
                          "raw": "1111",
                          "credId": "cf0867d1-02aa-4bcf-a7bc-be7eb5eae19e",
                          "credDefId": "did:omn:NcYxiDXkpYi6ov5FcYDi1e:3:CL:did:omn:NcYxiDXkpYi6ov5FcYDi1e:2:mdl:1.0:Tag1"
                        }
                      ]
                    },
                    "attributeReferent1": {
                      "name": "zkpsex",
                      "checkRevealed": true,
                      "referent": [
                        {
                          "raw": "male",
                          "credId": "cf0867d1-02aa-4bcf-a7bc-be7eb5eae19e",
                          "credDefId": "did:omn:NcYxiDXkpYi6ov5FcYDi1e:3:CL:did:omn:NcYxiDXkpYi6ov5FcYDi1e:2:mdl:1.0:Tag1"
                        }
                      ]
                    }
                  },
                  "predicateReferent": {
                    "predicateReferent1": {
                      "name": "zkpbirth",
                      "check_revealed": false,
                      "referent": [
                        {
                          "raw": "19840402",
                          "credId": "cf0867d1-02aa-4bcf-a7bc-be7eb5eae19e",
                          "credDefId": "did:omn:NcYxiDXkpYi6ov5FcYDi1e:3:CL:did:omn:NcYxiDXkpYi6ov5FcYDi1e:2:mdl:1.0:Tag1"
                        }
                      ]
                    }
                  }
                }
                """;
        AvailableReferent availableReferent = GsonWrapper.getGson().fromJson(availableReferentDummyStr, AvailableReferent.class);

        Map<String, String> selfAttr = new HashMap<String, String>();

//        Map<String, AttrReferent> selfAttrs = availableReferent.getSelfAttrReferent();
//        for (String key : selfAttrs.keySet()) {
//            AttrReferent attrRef = selfAttrs.get(key);
//            selectedUserReferent.add(new UserReferent.Builder()
//                    .setReferentKey(key)
//                    .setReferentName(attrRef.getName())
//                    .setRevealed(true)
//                    .build());
//
//            selfAttr.put(key, "test text");
//        }
//
//        // attr_referent
//        Map<String, AttrReferent> attrs = availableReferent.getAttrReferent();
//        for (String key : attrs.keySet()) {
//            AttrReferent attrRef = attrs.get(key);
//
//            selectedUserReferent.add(new UserReferent.Builder()
//                    .setReferentKey(key)
//                    .setReferentName(attrRef.getName())
//                    .setRaw(attrRef.getAttrSubReferent().get(0).getRaw())
//                    .setCredentialId(attrRef.getAttrSubReferent().get(0).getCredentialId())
//                    .setRevealed(true)
//                    .build());
//        }
//
//        // predicates_referent
//        Map<String, PredicateReferent> predicates = availableReferent.getPredicateReferent();
//        for (String key : predicates.keySet()) {
//            PredicateReferent predicateReferent = predicates.get(key);
//
//            selectedUserReferent.add(new UserReferent.Builder()
//                    .setReferentKey(key)
//                    .setReferentName(predicateReferent.getName())
//                    .setRaw(predicateReferent.getPredicateSubReferent().get(0).getRaw())
//                    .setCredentialId(predicateReferent.getPredicateSubReferent().get(0).getCredentialId())
//                    .setRevealed(false)
//                    .build());
//        }

        String selecteUserReferentDummyStr = """
            [
              {
                "credId": "cf0867d1-02aa-4bcf-a7bc-be7eb5eae19e",
                "raw": "seoul",
                "referentKey": "attributeReferent3",
                "referentName": "zkpaddr",
                "isRevealed": true
              },
              {
                "credId": "cf0867d1-02aa-4bcf-a7bc-be7eb5eae19e",
                "raw": "1111",
                "referentKey": "attributeReferent2",
                "referentName": "zkpasort",
                "isRevealed": true
              },
              {
                "credId": "cf0867d1-02aa-4bcf-a7bc-be7eb5eae19e",
                "raw": "male",
                "referentKey": "attributeReferent1",
                "referentName": "zkpsex",
                "isRevealed": true
              },
              {
                "credId": "cf0867d1-02aa-4bcf-a7bc-be7eb5eae19e",
                "raw": "19840402",
                "referentKey": "predicateReferent1",
                "referentName": "zkpbirth",
                "isRevealed": false
              }
            ]
        """;

        List<UserReferent> selectedUserReferent = GsonWrapper.getGson().fromJson(selecteUserReferentDummyStr, List.class);
        WalletLogger.getInstance().d("selectedUserReferent: "+GsonWrapper.getGsonPrettyPrinting().toJson(selectedUserReferent));

//        ReferentInfo referentInfo = zkpManager.createReferent(selectedUserReferent);

        String proofDummyStr = """
