import { expect } from 'chai'
import { ethers } from 'hardhat'
import { ResourceProvisioning } from '../typechain-types'

describe('ResourceProvisioning', function () {
  let contract: ResourceProvisioning
  let owner: any
  let addr1: any

  beforeEach(async function () {
    ;[owner, addr1] = await ethers.getSigners()

    const ResourceProvisioningFactory = await ethers.getContractFactory('ResourceProvisioning')
    contract = await ResourceProvisioningFactory.deploy()
    await contract.waitForDeployment()
  })

  describe('Resource Provisioning', function () {
    it('Should provision a new resource', async function () {
      const tx = await contract.provisionResource(
        'resource-001',
        'us-east-1',
        'datacenter-1',
        0, // VM
        '{"cpu": 4, "memory": 8192}'
      )

      await expect(tx)
        .to.emit(contract, 'ResourceProvisioned')
        .withArgs('resource-001', 'us-east-1', 0, owner.address, await ethers.provider.getBlockNumber())

      const resource = await contract.getResource('resource-001')
      expect(resource.resourceId).to.equal('resource-001')
      expect(resource.active).to.equal(true)
    })

    it('Should not allow provisioning duplicate resource', async function () {
      await contract.provisionResource(
        'resource-001',
        'us-east-1',
        'datacenter-1',
        0,
        '{}'
      )

      await expect(
        contract.provisionResource(
          'resource-001',
          'us-east-1',
          'datacenter-1',
          0,
          '{}'
        )
      ).to.be.revertedWith('Resource already exists')
    })

    it('Should deprovision a resource', async function () {
      await contract.provisionResource(
        'resource-001',
        'us-east-1',
        'datacenter-1',
        0,
        '{}'
      )

      const tx = await contract.deprovisionResource('resource-001')
      await expect(tx).to.emit(contract, 'ResourceDeprovisioned')

      const resource = await contract.getResource('resource-001')
      expect(resource.active).to.equal(false)
    })
  })
})

