export interface StandardCurve {
  name: string;
  p: string;
  a: string;
  b: string;
  G: string;
  n: string;
  h: string;
}

export const standardCurves: StandardCurve[] = [
  {
    name: 'secp192r1',
    p: 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF',
    a: 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC',
    b: '64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1',
    G: '04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811',
    n: 'FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831',
    h: '01'
  },
  {
    name: 'secp224r1',
    p: 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001',
    a: 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE',
    b: 'B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4',
    G: '04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34',
    n: 'FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D',
    h: '01'
  },
  {
    name: 'secp256r1',
    p: 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF',
    a: 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC',
    b: '5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B',
    G: '046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5',
    n: 'FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551',
    h: '01',
  },
  {
    name: 'secp384r1',
    p: 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF',
    a: 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC',
    b: 'B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF',
    G: '04AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F',
    n: 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973',
    h: '01',
  },
  {
    name: 'secp521r1',
    p: '01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF',
    a: '01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC',
    b: '0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00',
    G: '0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650',
    n: '01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409',
    h: '01',
  },
  {
    name: 'brainpoolP192r1',
    p: 'C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297',
    a: '6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF',
    b: '469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9',
    G: '04C0A0647EAA7F9B8EE7C1AC4D77FC94CA14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F',
    n: 'C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294',
    h: '01',
  },
  {
    name: 'brainpoolP224r1',
    p: 'd7c134aa264366862a18302575d1d787b09f075797da89f57ec8c0ff',
    a: '68a5e62ca9ce6c1c299803a6c1530b514e182ad8b0042a59cad29f43',
    b: '2580f63ccfe44138870713b1a92369e33e2135d266dbb372386c400b',
    G: '040d9029ad2c7e5cf4340823b2a87dc68c9e4ce3174c1e6efdee12c07d58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd',
    n: 'd7c134aa264366862a18302575d0fb98d116bc4b6ddebca3a5a7939f',
    h: '01',
  },
  {
    name: 'brainpoolP256r1',
    p: 'A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377',
    a: '7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9',
    b: '26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6',
    G: '048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997',
    n: 'A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7',
    h: '01',
  },
  {
    name: 'brainpoolP384r1',
    p: '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53',
    a: '7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826',
    b: '04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11',
    G: '041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315',
    n: '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565',
    h: '01',
  },
  {
    name: 'brainpoolP512r1',
    p: 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3',
    a: '7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA',
    b: '3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723',
    G: '0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892',
    n: 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069',
    h: '01',
  },
];

export function normalizeHex(hex: string): string {
  return hex.toLowerCase().replace(/^0x/, '').replace(/^00/, '');
}

export function identifyCurve(params: any): string {
  const normalizedParams = {
    p: normalizeHex(params.p),
    a: normalizeHex(params.a),
    b: normalizeHex(params.b),
    G: normalizeHex(params.G),
    n: normalizeHex(params.n),
    h: normalizeHex(params.h),
  };

  for (const curve of standardCurves) {
    if (
      normalizedParams.p === normalizeHex(curve.p) &&
      normalizedParams.a === normalizeHex(curve.a) &&
      normalizedParams.b === normalizeHex(curve.b) &&
      normalizedParams.G === normalizeHex(curve.G) &&
      normalizedParams.n === normalizeHex(curve.n) &&
      normalizedParams.h === normalizeHex(curve.h)
    ) {
      return curve.name;
    }
  }
  console.log('Unknown curve:', normalizedParams);
  return 'Unknown curve';
}

export function getECDSACurveBits(curveName: string): string {
  const curveBits: { [key: string]: number } = {
    secp224r1: 224,
    secp256r1: 256,
    secp384r1: 384,
    secp521r1: 521,
    brainpoolP224r1: 224,
    brainpoolP256r1: 256,
    brainpoolP384r1: 384,
    brainpoolP512r1: 512,
  };
  if (curveName in curveBits) {
    return curveBits[curveName].toString();
  }
  console.log('\x1b[31m%s\x1b[0m', `curve name ${curveName} not found in curveBits`);
  return 'unknown';
}
export function getCurveForElliptic(curveName: string): string {
  const curves = {
    secp224r1: 'p224',
    secp256r1: 'p256',
    secp384r1: 'p384',
    secp521r1: 'p521',
    brainpoolP224r1: 'brainpoolP224r1',
    brainpoolP256r1: 'brainpoolP256r1',
    brainpoolP384r1: 'brainpoolP384r1',
    brainpoolP512r1: 'brainpoolP512r1',
  };

  if (!curves[curveName]) {
    throw new Error('Invalid curve: ' + curveName);
  }

  return curves[curveName];
}
