import * as EthCrypto from "eth-crypto";
import axios from "axios";
import hasha from "hasha";
import { CertificateHistoryResponseEntryInterface } from "@minespider/core-sdk";

export interface CertificateCacheServiceAdapterInterface {
  getCertificate(uuid: string, privateKey: string): Promise<any>;
  getCertificates(ownerUuid: string, privateKey: string): Promise<any>;
  registerClient(clientDTO: ClientDTO): Promise<void>;
  getCertificateHistoryByOwner(
    entityId: string
  ): Promise<CertificateHistoryResponseEntryInterface[]>;
  getCertificateHistoryByCertificate(
    certificateUuid: string,
    parentsDepth?: number,
    childrenDepth?: number
  ): Promise<CertificateHistoryResponseEntryInterface[]>;
}

export interface ClientDTO {
  uuid: string,
  type: number,
  mnemonic: string,
  publicKey: string,
}

export interface CertificateHistoryResponseInterface {
  meta: object;
  content: CertificateHistoryResponseEntryInterface[];
}

export class CertificateCacheServiceAdapter {
  constructor(private certificateCacheServiceEndpoint: string) {}

  async getCertificate(uuid: string, privateKey: string) {
    const signature = EthCrypto.sign(
      privateKey,
      hasha(uuid.toLowerCase(), {
        algorithm: "sha256",
      })
    );
    const response = await axios.get(
      `${this.certificateCacheServiceEndpoint}/certificate/${uuid}?signature=${signature}`
    );

    return response.data;
  }

  async getCertificates(ownerUuid: string, privateKey: string) {
    const signature = EthCrypto.sign(
      privateKey,
      hasha(ownerUuid.toLowerCase(), {
        algorithm: "sha256",
      })
    );
    const response = await axios.get(
      `${this.certificateCacheServiceEndpoint}/certificates/findByOwner/${ownerUuid}?signature=${signature}`
    );

    return response.data.items;
  }

  async registerClient(clientDTO: ClientDTO) {
    await axios.post(`${this.certificateCacheServiceEndpoint}/client`, clientDTO);
  }

  async getCertificateHistoryByOwner(
    entityId: string
  ): Promise<CertificateHistoryResponseEntryInterface[]> {
    return new Promise<CertificateHistoryResponseEntryInterface[]>(
      async (resolve, reject) => {
        try {
          let response = await axios.get(
            this.certificateCacheServiceEndpoint + "/certificates/history/by-owner",
            {
              params: {
                entityId
              }
            }
          );

          resolve(response.data.content);
        } catch (error) {
          reject(error);
        }
      }
    );
  }

  async getCertificateHistoryByCertificate(
    uuid: string,
    parentsDepth: number = 10,
    childrenDepth: number = 10
  ): Promise<CertificateHistoryResponseEntryInterface[]> {
    return new Promise<CertificateHistoryResponseEntryInterface[]>(
      async (resolve, reject) => {
        try {
          let response = await axios.get(
            this.certificateCacheServiceEndpoint + "/certificates/history",
            {
              params: {
                uuid,
                parentsDepth,
                childrenDepth
              }
            }
          );

          resolve(response.data.content);
        } catch (error) {
          reject(error);
        }
      }
    );
  }
}