import {
  abi as FACTORY_ABI,
  bytecode as FACTORY_BYTECODE,
} from '@airdao/astra-cl-core/artifacts/contracts/AstraCLFactory.sol/AstraCLFactory.json'
import { abi as FACTORY_CLASSIC_ABI, bytecode as FACTORY_CLASSIC_BYTECODE } from '../contracts/AstraFactory.json'
import { Fixture } from 'ethereum-waffle'
import { ethers, waffle } from 'hardhat'
import { IAstraCLFactory, ISAMB, MockTimeSwapRouter } from '../../typechain'

import SAMB from '../contracts/SAMB.json'
import { Contract } from '@ethersproject/contracts'
import { constants } from 'ethers'

const wethFixture: Fixture<{ samb: ISAMB }> = async ([wallet]) => {
  const samb = (await waffle.deployContract(wallet, {
    bytecode: SAMB.bytecode,
    abi: SAMB.abi,
  })) as ISAMB

  return { samb }
}

export const ClassicFactoryFixture: Fixture<{ factory: Contract }> = async ([wallet]) => {
  const factory = await waffle.deployContract(
    wallet,
    {
      bytecode: FACTORY_CLASSIC_BYTECODE,
      abi: FACTORY_CLASSIC_ABI,
    },
    [constants.AddressZero]
  )

  return { factory }
}

const CLCoreFactoryFixture: Fixture<IAstraCLFactory> = async ([wallet]) => {
  return (await waffle.deployContract(wallet, {
    bytecode: FACTORY_BYTECODE,
    abi: FACTORY_ABI,
  })) as IAstraCLFactory
}

export const CLRouterFixture: Fixture<{
  samb: ISAMB
  factory: IAstraCLFactory
  router: MockTimeSwapRouter
}> = async ([wallet], provider) => {
  const { samb } = await wethFixture([wallet], provider)
  const factory = await CLCoreFactoryFixture([wallet], provider)

  const router = (await (
    await ethers.getContractFactory('MockTimeSwapRouter')
  ).deploy(factory.address, samb.address)) as MockTimeSwapRouter

  return { factory, samb, router }
}
