import "../../../types/config.js";
import type {
  SensitiveString,
  ResolvedConfigurationVariable,
} from "../../../types/config.js";

declare module "../../../types/config.js" {
  export interface TestPathsUserConfig {
    solidity?: string;
  }

  export interface TestPathsConfig {
    solidity: string;
  }
}

declare module "../../../types/test.js" {
  export interface SolidityTestFuzzConfigBase {
    failurePersistDir?: string;
    failurePersistFile?: string;
    runs?: number;
    maxTestRejects?: number;
    seed?: string;
    dictionaryWeight?: number;
    includeStorage?: boolean;
    includePushBytes?: boolean;
  }

  export interface SolidityTestFuzzConfig extends SolidityTestFuzzConfigBase {
    seed: string;
  }

  export interface SolidityTestConfigBase {
    timeout?: number;
    fsPermissions?: {
      readWriteFile?: string[];
      readFile?: string[];
      writeFile?: string[];
      dangerouslyReadWriteDirectory?: string[];
      readDirectory?: string[];
      dangerouslyWriteDirectory?: string[];
    };
    isolate?: boolean;
    ffi?: boolean;
    allowInternalExpectRevert?: boolean;
    from?: string; // 0x-prefixed hex string
    txOrigin?: string; // 0x-prefixed hex string
    initialBalance?: bigint;
    blockBaseFeePerGas?: bigint;
    coinbase?: string; // 0x-prefixed hex string
    blockTimestamp?: bigint;
    prevRandao?: bigint;
    gasLimit?: bigint;
    blockGasLimit?: bigint | false;

    fuzz?: SolidityTestFuzzConfigBase;
    invariant?: {
      failurePersistDir?: string;
      runs?: number;
      depth?: number;
      failOnRevert?: boolean;
      callOverride?: boolean;
      dictionaryWeight?: number;
      includeStorage?: boolean;
      includePushBytes?: boolean;
      shrinkRunLimit?: number;
    };
  }

  export interface SolidityTestForkingUserConfig {
    url?: SensitiveString;
    blockNumber?: bigint;
    rpcEndpoints?: Record<string, SensitiveString>;
  }

  export interface SolidityTestUserConfig extends SolidityTestConfigBase {
    forking?: SolidityTestForkingUserConfig;
  }

  export interface HardhatTestUserConfig {
    solidity?: SolidityTestUserConfig;
  }

  export interface SolidityTestForkingConfig {
    url?: ResolvedConfigurationVariable;
    blockNumber?: bigint;
    rpcEndpoints?: Record<string, ResolvedConfigurationVariable>;
  }

  export interface SolidityTestConfig extends SolidityTestConfigBase {
    fuzz: SolidityTestFuzzConfig;
    forking?: SolidityTestForkingConfig;
  }
  export interface HardhatTestConfig {
    solidity: SolidityTestConfig;
  }
}
