declare global {
  interface LocalStorage {
    setItem(key: string, value: any): void;
    getItem(key: string): any;
    removeItem(key: string): void;
  }

  namespace NodeJS {
    interface Global {
      window: {
        localStorage: LocalStorage;
        sessionStorage: LocalStorage;
      };
      File: typeof File;
    }
  }
}

class FakeLocalStorage implements LocalStorage {
  private storage: {
    [key: string]: any;
  };

  constructor() {
    this.storage = {};
  }

  setItem(key: string, value: any) {
    this.storage[key] = value;
  }

  getItem(key: string): any {
    return this.storage[key];
  }

  removeItem(key: string): void {
    delete this.storage[key];
  }
}

global.window = {
  localStorage: new FakeLocalStorage(),
  sessionStorage: new FakeLocalStorage()
};

global.File = require("../../src/StorageBundle/FileAPI/File").File;

import { EthersJrpcAdapter, Minespider } from "@minespider/core-sdk";
import * as dotenv from "dotenv";
import { MinespiderFacade } from "../../src/MinespiderBundle/Business/MinespiderFacade";
import { createCertificate } from "./createCertificate";
import { sellCertificate } from "./sellCertificate";
import { splitAndSellCertificate } from "./splitAndSellCertificate";
import { MinespiderModel } from "../../src/MinespiderBundle/Business/Model/MinespiderModel";

dotenv.config();

const rootAdapter = new EthersJrpcAdapter(
  String(process.env.ROOT_ETH_PRIVATE_KEY)
);
rootAdapter.init(
  String(process.env.CORE_CONTRACT_ADDRESS),
  String(process.env.CERTIFICATES_CONTRACT_ADDRESS),
  String(process.env.BALANCES_CONTRACT_ADDRESS)
);

const producerAdapter = new EthersJrpcAdapter(
  String(process.env.PRODUCER_ETH_PRIVATE_KEY)
);
producerAdapter.init(
  String(process.env.CORE_CONTRACT_ADDRESS),
  String(process.env.CERTIFICATES_CONTRACT_ADDRESS),
  String(process.env.BALANCES_CONTRACT_ADDRESS)
);

const rootSdk = new Minespider(rootAdapter);
const producerSdk = new Minespider(producerAdapter);
const rootFacade = new MinespiderFacade(
  new MinespiderModel(new Minespider(rootAdapter, "http://localhost:8545"))
);
const producerFacade = new MinespiderFacade(
  new MinespiderModel(new Minespider(producerAdapter, "http://localhost:8545"))
);

it("should create a primary certificate", async () => {
  const certificateEnvelope = await createCertificate(producerFacade, 100);

  const soldToRootCertificateEnvelopeAddress = await sellCertificate(
    producerFacade,
    certificateEnvelope,
    100,
    await rootSdk.getCurrentAccountAddress()
  );

  const soldToRootCertificateEnvelope = await rootFacade.downloadCertificateEnvelope(
    soldToRootCertificateEnvelopeAddress
  );

  await splitAndSellCertificate(
    rootFacade,
    soldToRootCertificateEnvelope,
    40,
    await producerSdk.getCurrentAccountAddress()
  );
});
