/**
 * @packageDocumentation
 * @module Utils-Constants
 */

import BN from "bn.js"

export const PrivateKeyPrefix: string = "PrivateKey-"
export const NodeIDPrefix: string = "NodeID-"
export const PrimaryAssetAlias: string = "DCM"
export const MainnetAPI: string = "34.134.243.192"
export const TestnetAPI: string = "23.20.122.102"

export interface ACT {
  blockchainID: string
  alias: string
  vm: string
  fee?: BN
  gasPrice: BN | number
  chainID?: number
  minGasPrice?: BN
  maxGasPrice?: BN
  txBytesGas?: number
  costPerSignature?: number
  txFee?: BN
  dcmAssetID?: string
}
export interface AST {
  blockchainID: string
  alias: string
  vm: string
  creationTxFee: BN | number
  mintTxFee: BN
  dcmAssetID?: string
  txFee?: BN | number
  fee?: BN
}
export interface ATH {
  blockchainID: string
  alias: string
  vm: string
  creationTxFee: BN | number
  createSubnetTx: BN | number
  createChainTx: BN | number
  minConsumption: number
  maxConsumption: number
  maxStakingDuration: BN
  maxSupply: BN
  minStake: BN
  minStakeDuration: number
  maxStakeDuration: number
  minDelegationStake: BN
  minDelegationFee: BN
  dcmAssetID?: string
  txFee?: BN | number
  fee?: BN
}
export interface Network {
  ACT: ACT
  hrp: string
  AST: AST
  ATH: ATH
  [key: string]: ACT | AST | ATH | string
}
export interface Networks {
  [key: number]: Network
}

export const NetworkIDToHRP: object = {
  0: "custom",
  1: "dcm",
  5: "test",
  6: "canary",
  1337: "custom",
  12345: "local",
  2: "melbourne",
  3: "goldcoast"
}

export const HRPToNetworkID: object = {
  manhattan: 0,
  dcm: 1,
  test: [5],
  canary: 6,
  custom: 1337,
  local: 12345,
  melbourne: 2,
  goldcoast: 3,
}

export const NetworkIDToNetworkNames: object = {
  0: ["Manhattan"],
  1: ["Dcomm", "Mainnet"],
  5: ["Testnet"],
  6: ["Canary"],
  1337: ["Custom Network"],
  12345: ["Local Network"],
  2: ["melbourne"],
  3: ["goldcoast"]
}

export const NetworkNameToNetworkID: object = {
  Manhattan: 0,
  Dcomm: 1,
  Mainnet: 1,
  Canary: 6,
  Testnet: 5,
  Custom: 1337,
  "Custom Network": 1337,
  Local: 12345,
  "Local Network": 12345,
  melbourne: 2,
  goldcoast: 3,
}

export const FallbackHRP: string = "custom"
export const FallbackNetworkName: string = "Custom Network"
export const FallbackEVMChainID: number = 43112

export const DefaultNetworkID: number = 1

export const AuthorityChainID: string = "11111111111111111111111111111111LpoYY"
export const PrimaryNetworkID: string = "11111111111111111111111111111111LpoYY"
export const ASTChainAlias: string = "AST"
export const ACTChainAlias: string = "ACT"
export const ATHChainAlias: string = "ATH"
export const ASTChainVMName: string = "dvm"
export const ACTChainVMName: string = "evm"
export const ATHChainVMName: string = "authorityvm"

// DO NOT use the following private keys and/or mnemonic on Testnet
// This address/account is for testing on the local avash network
export const DefaultLocalGenesisPrivateKey: string =
  "ewoqjP7PxY4yr3iLTpLisriqt94hdyDFNgchSxGGztUrTXtNN"
export const DefaultEVMLocalGenesisPrivateKey: string =
  "0x56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027"
export const DefaultEVMLocalGenesisAddress: string =
  "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC"
export const mnemonic: string =
  "output tooth keep tooth bracket fox city sustain blood raise install pond stem reject long scene clap gloom purpose mean music piece unknown light"

export const ONEDCM: BN = new BN(1000000000)

export const DECIDCM: BN = ONEDCM.div(new BN(10))

export const CENTIDCM: BN = ONEDCM.div(new BN(100))

export const MILLIDCM: BN = ONEDCM.div(new BN(1000))

export const MICRODCM: BN = ONEDCM.div(new BN(1000000))

export const NANODCM: BN = ONEDCM.div(new BN(1000000000))

export const WEI: BN = new BN(1)

export const GWEI: BN = WEI.mul(new BN(1000000000))

export const DCMGWEI: BN = NANODCM.clone()

export const DCMSTAKECAP: BN = ONEDCM.mul(new BN(3000000))

// Start Manhattan
const n0X: AST = {
  blockchainID: "2vrXWHgGxh5n3YsLHMV16YVVJTpT4z45Fmb4y3bL6si8kLCyg9",
  alias: ASTChainAlias,
  vm: ASTChainVMName,
  fee: MILLIDCM,
  creationTxFee: CENTIDCM,
  mintTxFee: MILLIDCM
}

const n0P: ATH = {
  blockchainID: AuthorityChainID,
  alias: ATHChainAlias,
  vm: ATHChainVMName,
  fee: MILLIDCM,
  creationTxFee: CENTIDCM,
  createSubnetTx: ONEDCM,
  createChainTx: ONEDCM,
  minConsumption: 0.1,
  maxConsumption: 0.12,
  maxStakingDuration: new BN(31536000),
  maxSupply: new BN(720000000).mul(ONEDCM),
  minStake: ONEDCM.mul(new BN(2000)),
  minStakeDuration: 2 * 7 * 24 * 60 * 60, //two weeks
  maxStakeDuration: 365 * 24 * 60 * 60, // one year
  minDelegationStake: ONEDCM.mul(new BN(25)),
  minDelegationFee: new BN(2)
}

const n0C: ACT = {
  blockchainID: "2fFZQibQXcd6LTE4rpBPBAkLVXFE91Kit8pgxaBG1mRnh5xqbb",
  alias: ACTChainAlias,
  vm: ACTChainVMName,
  fee: MILLIDCM,
  gasPrice: GWEI.mul(new BN(470)), //equivalent to gas price
  chainID: 43111
}
// End Manhattan

// Start mainnet
let dcmAssetID: string = "FvwEAhmxKfeiG8SnEvq42hc6whRyY3EFYAvebMqDNDGCgxN5Z"
const n1X: AST = {
  blockchainID: "2oYMBNV4eNHyqk2fjjV5nVQLDbtmNJzq5s3qs3Lo6ftnC6FByM",
  dcmAssetID: dcmAssetID,
  alias: ASTChainAlias,
  vm: ASTChainVMName,
  txFee: MILLIDCM,
  creationTxFee: CENTIDCM,
  mintTxFee: MILLIDCM
}

const n1P: ATH = {
  blockchainID: AuthorityChainID,
  dcmAssetID: dcmAssetID,
  alias: ATHChainAlias,
  vm: ATHChainVMName,
  txFee: MILLIDCM,
  createSubnetTx: ONEDCM,
  createChainTx: ONEDCM,
  creationTxFee: CENTIDCM,
  minConsumption: 0.1,
  maxConsumption: 0.12,
  maxStakingDuration: new BN(31536000),
  maxSupply: new BN(720000000).mul(ONEDCM),
  minStake: ONEDCM.mul(new BN(2000)),
  minStakeDuration: 2 * 7 * 24 * 60 * 60, //two weeks
  maxStakeDuration: 365 * 24 * 60 * 60, // one year
  minDelegationStake: ONEDCM.mul(new BN(25)),
  minDelegationFee: new BN(2)
}

const n1C: ACT = {
  blockchainID: "2q9e4r6Mu3U68nU1fYjgbR6JvwrRx36CohpAX5UQxse55x1Q5",
  alias: ACTChainAlias,
  vm: ACTChainVMName,
  txBytesGas: 1,
  costPerSignature: 1000,
  // DEPRECATED - txFee
  // WILL BE REMOVED IN NEXT MAJOR VERSION BUMP
  txFee: MILLIDCM,
  // DEPRECATED - gasPrice
  // WILL BE REMOVED IN NEXT MAJOR VERSION BUMP
  gasPrice: GWEI.mul(new BN(225)),
  minGasPrice: GWEI.mul(new BN(25)),
  maxGasPrice: GWEI.mul(new BN(1000)),
  chainID: 43114
}
// End Mainnet

// Start Canary
dcmAssetID = "2iP8efnRxnsain5NVsZ6NGddZCRWZVm2RezqKNiKANXPqQBbqm"
const n5X: AST = {
  blockchainID: "2S1QKgcu1CAaKTkMA2gtQUEpsrWkJaJAZp5RuJQFuEamTVdzEf",
  dcmAssetID: dcmAssetID,
  alias: ASTChainAlias,
  vm: ASTChainVMName,
  txFee: MILLIDCM,
  creationTxFee: CENTIDCM,
  mintTxFee: MILLIDCM
}

const n5P: ATH = {
  blockchainID: AuthorityChainID,
  dcmAssetID: dcmAssetID,
  alias: ATHChainAlias,
  vm: ATHChainVMName,
  txFee: MILLIDCM,
  creationTxFee: CENTIDCM,
  createSubnetTx: ONEDCM,
  createChainTx: ONEDCM,
  minConsumption: 0.1,
  maxConsumption: 0.12,
  maxStakingDuration: new BN(31536000),
  maxSupply: new BN(720000000).mul(ONEDCM),
  minStake: ONEDCM,
  minStakeDuration: 24 * 60 * 60, //one day
  maxStakeDuration: 365 * 24 * 60 * 60, // one year
  minDelegationStake: ONEDCM,
  minDelegationFee: new BN(2)
}

const n5C: ACT = {
  blockchainID: "2GqHL4FkzFryJSkyxsbWqqwkRCARHdugx3EHPbnXpE6X7LUgt7",
  alias: ACTChainAlias,
  vm: ACTChainVMName,
  txBytesGas: 1,
  costPerSignature: 1000,
  // DEPRECATED - txFee
  // WILL BE REMOVED IN NEXT MAJOR VERSION BUMP
  txFee: MILLIDCM,
  // DEPRECATED - gasPrice
  // WILL BE REMOVED IN NEXT MAJOR VERSION BUMP
  gasPrice: GWEI.mul(new BN(225)),
  minGasPrice: GWEI.mul(new BN(25)),
  maxGasPrice: GWEI.mul(new BN(1000)),
  chainID: 5002
}
// End Canary

// Start GoldCoast
dcmAssetID = "jQUKHKoVVo2rncCSKAau8cUwgA638zowDxhk7Me8sFnP7TrbS"
const n8X: AST = {
  blockchainID: "CYMrs3H4kj711TwjSGcdQ4owfhcF5gwWtzekGj6wumQLFwftd",
  dcmAssetID: dcmAssetID,
  alias: ASTChainAlias,
  vm: ASTChainVMName,
  txFee: MILLIDCM,
  creationTxFee: CENTIDCM,
  mintTxFee: MILLIDCM
}

const n8P: ATH = {
  blockchainID: AuthorityChainID,
  dcmAssetID: dcmAssetID,
  alias: ATHChainAlias,
  vm: ATHChainVMName,
  txFee: MILLIDCM,
  creationTxFee: CENTIDCM,
  createSubnetTx: ONEDCM,
  createChainTx: ONEDCM,
  minConsumption: 0.1,
  maxConsumption: 0.12,
  maxStakingDuration: new BN(31536000),
  maxSupply: new BN(720000000).mul(ONEDCM),
  minStake: ONEDCM,
  minStakeDuration: 24 * 60 * 60, //one day
  maxStakeDuration: 365 * 24 * 60 * 60, // one year
  minDelegationStake: ONEDCM,
  minDelegationFee: new BN(2)
}

const n8C: ACT = {
  blockchainID: "2jYyCtM8b1HDRP9rnK7JvPYNNdUM68N8jnn6RexJjVn4GyvDtj",
  alias: ACTChainAlias,
  vm: ACTChainVMName,
  txBytesGas: 1,
  costPerSignature: 1000,
  // DEPRECATED - txFee
  // WILL BE REMOVED IN NEXT MAJOR VERSION BUMP
  txFee: MILLIDCM,
  // DEPRECATED - gasPrice
  // WILL BE REMOVED IN NEXT MAJOR VERSION BUMP
  gasPrice: GWEI.mul(new BN(225)),
  minGasPrice: GWEI.mul(new BN(25)),
  maxGasPrice: GWEI.mul(new BN(1000)),
  chainID: 5004
}
// End Goldcoast

// Start Melbourne
dcmAssetID = "21jcXzWC3GNFjDW4GGHor8GmapDPac1wD86C1LoV8qHjJQKZ5s"
const n7X: AST = {
  blockchainID: "2hN6GMRxTkSmd8R7oAkyTanJ1bAhHxPsTaXNXr3XqmkUAQfPar",
  dcmAssetID: dcmAssetID,
  alias: ASTChainAlias,
  vm: ASTChainVMName,
  txFee: MILLIDCM,
  creationTxFee: CENTIDCM,
  mintTxFee: MILLIDCM
}

const n7P: ATH = {
  blockchainID: AuthorityChainID,
  dcmAssetID: dcmAssetID,
  alias: ATHChainAlias,
  vm: ATHChainVMName,
  txFee: MILLIDCM,
  creationTxFee: CENTIDCM,
  createSubnetTx: ONEDCM,
  createChainTx: ONEDCM,
  minConsumption: 0.1,
  maxConsumption: 0.12,
  maxStakingDuration: new BN(31536000),
  maxSupply: new BN(720000000).mul(ONEDCM),
  minStake: ONEDCM,
  minStakeDuration: 24 * 60 * 60, //one day
  maxStakeDuration: 365 * 24 * 60 * 60, // one year
  minDelegationStake: ONEDCM,
  minDelegationFee: new BN(2)
}

const n7C: ACT = {
  blockchainID: "2BNZYo7pEFTYA7Rm5HkkF6ApUNbv3Ve8rDmn6ZM9xRbtt6wcUp",
  alias: ACTChainAlias,
  vm: ACTChainVMName,
  txBytesGas: 1,
  costPerSignature: 1000,
  // DEPRECATED - txFee
  // WILL BE REMOVED IN NEXT MAJOR VERSION BUMP
  txFee: MILLIDCM,
  // DEPRECATED - gasPrice
  // WILL BE REMOVED IN NEXT MAJOR VERSION BUMP
  gasPrice: GWEI.mul(new BN(225)),
  minGasPrice: GWEI.mul(new BN(25)),
  maxGasPrice: GWEI.mul(new BN(1000)),
  chainID: 5002
}
// End Melbourne

// Start Testnet
dcmAssetID = "259cyNcbuCFcAvSJyomnKdpb96q3Vpfk2VHeNVrhkJgWFrxtf8"
const n6X: AST = {
  blockchainID: "2GYG2BRKH8EeSGhbhsGCH9shLfyDyFUrb1gxZDXDTtujQAQzde",
  dcmAssetID: dcmAssetID,
  alias: ASTChainAlias,
  vm: ASTChainVMName,
  txFee: MILLIDCM,
  creationTxFee: CENTIDCM,
  mintTxFee: MILLIDCM
}

const n6P: ATH = {
  blockchainID: AuthorityChainID,
  dcmAssetID: dcmAssetID,
  alias: ATHChainAlias,
  vm: ATHChainVMName,
  txFee: MILLIDCM,
  creationTxFee: CENTIDCM,
  createSubnetTx: ONEDCM,
  createChainTx: ONEDCM,
  minConsumption: 0.1,
  maxConsumption: 0.12,
  maxStakingDuration: new BN(31536000),
  maxSupply: new BN(720000000).mul(ONEDCM),
  minStake: ONEDCM,
  minStakeDuration: 24 * 60 * 60, //one day
  maxStakeDuration: 365 * 24 * 60 * 60, // one year
  minDelegationStake: ONEDCM,
  minDelegationFee: new BN(2)
}

const n6C: ACT = {
  blockchainID: "2LsJusjrbraWRAPW5LCkDGALZC88u619tYKp84uYpKjGUxXvoW",
  alias: ACTChainAlias,
  vm: ACTChainVMName,
  txBytesGas: 1,
  costPerSignature: 1000,
  // DEPRECATED - txFee
  // WILL BE REMOVED IN NEXT MAJOR VERSION BUMP
  txFee: MILLIDCM,
  // DEPRECATED - gasPrice
  // WILL BE REMOVED IN NEXT MAJOR VERSION BUMP
  gasPrice: GWEI.mul(new BN(225)),
  minGasPrice: GWEI.mul(new BN(25)),
  maxGasPrice: GWEI.mul(new BN(1000)),
  chainID: 5002
}
// End Testnet

// Start custom network
dcmAssetID = "BUuypiq2wyuLMvyhzFXcPyxPMCgSp7eeDohhQRqTChoBjKziC"
const n1337X: AST = { ...n5X }
n1337X.blockchainID = "qzfF3A11KzpcHkkqznEyQgupQrCNS6WV6fTUTwZpEKqhj1QE7"
n1337X.dcmAssetID = dcmAssetID
const n1337P: ATH = { ...n5P }
n1337P.blockchainID = AuthorityChainID
const n1337C: ACT = { ...n5C }
n1337C.blockchainID = "BR28ypgLATNS6PbtHMiJ7NQ61vfpT27Hj8tAcZ1AHsfU5cz88"
n1337C.dcmAssetID = dcmAssetID
n1337C.chainID = 43112
// End custom network

// Start local network
dcmAssetID = "2uzUUhRhAinSiLPqf7xxQTeXWx96nxSeYPY6tjnpnjNJZaUaWt"
const n12345X: AST = { ...n5X }
n12345X.blockchainID = "2UTAi8H8vAdtZeV5VrmNVrKpyXKsfZ13aJ8zwv3WUm2efPyYMx"
n12345X.dcmAssetID = dcmAssetID
const n12345P: ATH = { ...n5P }
n12345P.blockchainID = AuthorityChainID
const n12345C: ACT = { ...n5C }
n12345C.blockchainID = "13sSEaeYy8SrDxJn8LfKNWeQJQFhfT69iJAeZZMGcVafm5Rg4"
n12345C.dcmAssetID = dcmAssetID
n12345C.chainID = 5003
// End local network

export class Defaults {
  static network: Networks = {
    0: {
      hrp: NetworkIDToHRP[0],
      AST: n0X,
      "2vrXWHgGxh5n3YsLHMV16YVVJTpT4z45Fmb4y3bL6si8kLCyg9": n0X,
      ATH: n0P,
      "11111111111111111111111111111111LpoYY": n0P,
      ACT: n0C,
      "2fFZQibQXcd6LTE4rpBPBAkLVXFE91Kit8pgxaBG1mRnh5xqbb": n0C
    },
    1: {
      hrp: NetworkIDToHRP[1],
      AST: n1X,
      "2oYMBNV4eNHyqk2fjjV5nVQLDbtmNJzq5s3qs3Lo6ftnC6FByM": n1X,
      ATH: n1P,
      "11111111111111111111111111111111LpoYY": n1P,
      ACT: n1C,
      "2q9e4r6Mu3U68nU1fYjgbR6JvwrRx36CohpAX5UQxse55x1Q5": n1C
    },
    2: {
      hrp: NetworkIDToHRP[2],
      AST: n7X,
      "2hN6GMRxTkSmd8R7oAkyTanJ1bAhHxPsTaXNXr3XqmkUAQfPar": n7X,
      ATH: n7P,
      "11111111111111111111111111111111LpoYY": n7P,
      ACT: n7C,
      "2BNZYo7pEFTYA7Rm5HkkF6ApUNbv3Ve8rDmn6ZM9xRbtt6wcUp": n7C
    },
    3: {
      hrp: NetworkIDToHRP[3],
      AST: n8X,
      "CYMrs3H4kj711TwjSGcdQ4owfhcF5gwWtzekGj6wumQLFwftd": n8X,
      ATH: n8P,
      "11111111111111111111111111111111LpoYY": n8P,
      ACT: n8C,
      "2jYyCtM8b1HDRP9rnK7JvPYNNdUM68N8jnn6RexJjVn4GyvDtj": n8C
    },
    6: {
      hrp: NetworkIDToHRP[6],
      AST: n5X,
      "2S1QKgcu1CAaKTkMA2gtQUEpsrWkJaJAZp5RuJQFuEamTVdzEf": n5X,
      ATH: n5P,
      "11111111111111111111111111111111LpoYY": n5P,
      ACT: n5C,
      "2GqHL4FkzFryJSkyxsbWqqwkRCARHdugx3EHPbnXpE6X7LUgt7": n5C
    },
    5: {
      hrp: NetworkIDToHRP[5],
      AST: n6X,
      "2GYG2BRKH8EeSGhbhsGCH9shLfyDyFUrb1gxZDXDTtujQAQzde": n6X,
      ATH: n6P,
      "11111111111111111111111111111111LpoYY": n6P,
      ACT: n6C,
      "2LsJusjrbraWRAPW5LCkDGALZC88u619tYKp84uYpKjGUxXvoW": n6C
    },
    1337: {
      hrp: NetworkIDToHRP[1337],
      AST: n1337X,
      qzfF3A11KzpcHkkqznEyQgupQrCNS6WV6fTUTwZpEKqhj1QE7: n1337X,
      ATH: n1337P,
      "11111111111111111111111111111111LpoYY": n1337P,
      ACT: n1337C,
      BR28ypgLATNS6PbtHMiJ7NQ61vfpT27Hj8tAcZ1AHsfU5cz88: n1337C
    },
    12345: {
      hrp: NetworkIDToHRP[12345],
      AST: n12345X,
      "2UTAi8H8vAdtZeV5VrmNVrKpyXKsfZ13aJ8zwv3WUm2efPyYMx": n12345X,
      ATH: n12345P,
      "11111111111111111111111111111111LpoYY": n12345P,
      ACT: n12345C,
      "13sSEaeYy8SrDxJn8LfKNWeQJQFhfT69iJAeZZMGcVafm5Rg4": n12345C
    }
  }
}

/**
 * Rules used when merging sets
 */
export type MergeRule =
  | "intersection" // Self INTERSECT New
  | "differenceSelf" // Self MINUS New
  | "differenceNew" // New MINUS Self
  | "symDifference" // differenceSelf UNION differenceNew
  | "union" // Self UNION New
  | "unionMinusNew" // union MINUS differenceNew
  | "unionMinusSelf" // union MINUS differenceSelf
  | "ERROR" // generate error for testing
