// Copyright (C) 2020-2022 Notus Network
//
// Notus Network is free software distributed under the MIT software license,
// see the accompanying file LICENSE in the main directory of the
// project or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

import {BN} from 'bn.js';
import {
  NetworkLayer,
  NetworkType,
  PortNo,
  ListMainNodeIp,
  Bip39WordArray,
  Default_WordListArrayCount,
} from '../types';
import {Md5Hash, Sha1Hash} from './hash';

export function GetNetworkPort(
  NetworkLayer: NetworkLayer,
  NetworkType: NetworkType,
) {
  return PortNo[NetworkLayer][NetworkType];
}

export function MakeHttpListenerPath(
  ipAddress: string,
  port: number,
  UseSSL: boolean,
) {
  return 'http' + (UseSSL ? 's' : '') + '://' + ipAddress + ':' + port + '/';
}

export async function FindAvailableNode(
  url: string,
  NetworkType: NetworkType,
  Networklayer: NetworkLayer,
) {
  let res = '';
  for (let a = 0; a < ListMainNodeIp.length; a++) {
    try {
      res = await GetRequest(
        ListMainNodeIp[a] +
          GetNetworkPort(Networklayer, NetworkType).toString() +
          url,
      );
    } catch (ex) {
      continue;
    }
  }
  return res;
}

export function GetRequest<T>(url: string): Promise<T> {
  return fetch(url)
    .then(response => {
      if (!response.ok) {
        throw new Error(response.statusText);
      }
      return response.json() as Promise<{data: T}>;
    })
    .then(data => {
      return data.data;
    });
}

export function PostRequest<T>(url: string, object: T): Promise<T> {
  return fetch(url, {
    method: 'POST',
    body: JSON.stringify(object),
    headers: {'Content-type': 'application/json'},
  })
    .then(response => {
      if (!response.ok) {
        throw new Error(response.statusText);
      }
      return response.json() as Promise<{data: T}>;
    })
    .then(data => {
      return data.data;
    });
}

export function SeedPhraseList(): string[] {
  var wordList: string[] = [];
  for (var i = 0; i < Default_WordListArrayCount; i++) {
    wordList[i] = Bip39Keyword(
      parseInt(
        new BN(
          Sha1Hash(
            new Date().toLocaleTimeString() +
              Md5Hash(
                new Date().toLocaleString() +
                  getRandomInt(10000000, Number.MAX_SAFE_INTEGER).toString(),
              ),
          ),
          16,
        )
          .toString(10)
          .substring(0, 4),
      ),
    );
  }

  return wordList;
}

export function Bip39Keyword(Bip39WordIndexNo: number): string {
  Bip39WordIndexNo = Math.abs(Bip39WordIndexNo);

  while (true) {
    if (Bip39WordArray.length > Bip39WordIndexNo) {
      break;
    } else {
      Bip39WordIndexNo -= Bip39WordArray.length;
    }
  }

  return Bip39WordArray[Bip39WordIndexNo];
}

function getRandomInt(min: number, max: number): number {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
