// CI-portable config for `npx hardhat coverage`.
//
// This is a SEPARATE config on purpose. The production `hardhat.config.js` is
// never read by the coverage run and is never modified by it, so a coverage
// run cannot change the bytecode that gets compiled, tested or deployed.
//
// Difference from the internal config it is derived from: every path here is
// RELATIVE. The internal one hardcoded an absolute developer scratch directory,
// which meant it could not run on a CI runner at all. Relative paths are what
// make this file reproducible on a stranger's machine.
//
// COMPILER STRATEGY (this is the non-obvious part, documented so it is not
// "fixed" back into a broken state):
//
//   * The GLOBAL compiler stays production-like: solc 0.8.23, optimizer ON
//     runs:1, viaIR:true. Optimizer ON is what lets the deep,
//     optimizer-dependent contracts (for example AerePaymentChannels
//     .closeWithState) compile at all.
//
//   * Do NOT "just disable viaIR for coverage". That is the intuitive lever and
//     it is the wrong one. solidity-coverage's own plugin source
//     (plugins/hardhat.plugin.js) contains:
//
//         if (!settings.viaIR || irMinimum) settings.optimizer.enabled = false;
//
//     so turning viaIR off, or setting irMinimum, forces the optimizer OFF for
//     EVERY compilation job in the tree. That breaks the optimizer-dependent
//     contracts and produces stack-too-deep on strictly MORE files, not fewer.
//     Per-file overrides work precisely because the global job keeps viaIR true,
//     which leaves the plugin's optimizer setting alone.
//
//   * If a contract overflows the Yul stack ONLY once instrumented, give it a
//     per-file STACK_ALLOC_OVERRIDE below. Same mechanics as the plugin's
//     `irMinimum`, applied per file instead of globally.
require("@nomicfoundation/hardhat-toolbox"); // pulls in solidity-coverage

// optimizer OFF + Yul stack allocation: makes an INSTRUMENTED deep contract fit
// the 16-slot stack, without disabling the optimizer for the whole tree.
// eslint-disable-next-line no-unused-vars
const STACK_ALLOC_OVERRIDE = {
  version: "0.8.23",
  settings: {
    optimizer: {
      enabled: false,
      details: { yul: true, yulDetails: { stackAllocation: true, optimizerSteps: "" } },
    },
    viaIR: true,
  },
};

module.exports = {
  solidity: {
    compilers: [
      {
        version: "0.8.23",
        settings: {
          optimizer: { enabled: true, runs: 1 },
          viaIR: true,
        },
      },
    ],
    overrides: {
      // Cancun canary keeps its production override (0.8.24 / cancun / runs:200).
      "contracts/AereCancunCanary.sol": {
        version: "0.8.24",
        settings: {
          optimizer: { enabled: true, runs: 200 },
          evmVersion: "cancun",
        },
      },
      // NOTE: the internal tree also overrides three contracts/corebook/*.sol
      // files here. Those contracts are held private (see EXCLUDED-FILES.txt)
      // and are not present in this repository, so their overrides are omitted.
      // If you add a contract that fails to compile ONLY under coverage with a
      // "stack too deep" YulException, add it here as STACK_ALLOC_OVERRIDE.
    },
  },
  networks: {
    hardhat: {
      chainId: 31337,
      hardfork: "cancun",
      blockGasLimit: 2_000_000_000,
      allowUnlimitedContractSize: true,
      mining: { auto: true },
      accounts: {
        // Public, well-known Hardhat test mnemonic. It is deliberately the
        // standard throwaway. It holds nothing, on any network, ever.
        mnemonic:
          "test test test test test test test test test test test junk",
        count: 20,
        accountsBalance: "10000000000000000000000",
      },
    },
  },
  mocha: { timeout: 240000 },
  paths: {
    sources: "./contracts",
    tests: "./test",
    // Relative, and separate from ./cache and ./artifacts, so the instrumented
    // build never pollutes the production build outputs.
    cache: "./cache-coverage",
    artifacts: "./artifacts-coverage",
  },
};
