/**
 * Vaultfire Agent — Configuration
 *
 * Centralizes all environment-driven configuration, contract addresses,
 * and operational parameters for the Vaultfire Sentinel agent.
 *
 * Multichain support:
 *   Base mainnet is the PRIMARY / CANONICAL chain (default).
 *   Avalanche C-Chain is a supported SECONDARY chain.
 *   Set VAULTFIRE_CHAIN=avalanche to target Avalanche.
 *
 * Demo mode:
 *   Set DEMO_MODE=true to run a shortened demo loop suitable for
 *   Build Games showcases.  When DEMO_MODE is active and the chain
 *   is avalancheFuji, the agent runs through registration, bond
 *   discovery, and metrics reporting in a single pass then exits.
 */

import dotenv from 'dotenv';
import path from 'path';

// Load .env from the agent directory
dotenv.config({ path: path.resolve(__dirname, '..', '.env') });

// ---------------------------------------------------------------------------
// Environment helpers
// ---------------------------------------------------------------------------

function requireEnv(key: string): string {
  const value = process.env[key];
  if (!value) {
    throw new Error(`Missing required environment variable: ${key}`);
  }
  return value;
}

function optionalEnv(key: string, fallback: string): string {
  return process.env[key] || fallback;
}

function boolEnv(key: string, fallback: boolean): boolean {
  const raw = process.env[key];
  if (!raw) return fallback;
  return raw.toLowerCase() === 'true' || raw === '1';
}

function intEnv(key: string, fallback: number): number {
  const raw = process.env[key];
  if (!raw) return fallback;
  const parsed = parseInt(raw, 10);
  return isNaN(parsed) ? fallback : parsed;
}

// ---------------------------------------------------------------------------
// Deployed contract addresses on Base mainnet (Chain ID 8453) — PRIMARY
// ---------------------------------------------------------------------------

export const CONTRACTS = {
  ERC8004IdentityRegistry: '0xa7BD20bf5De63df949cA5Be2F20835978eCba81A',
  AIPartnershipBondsV2: '0x01C479F0c039fEC40c0Cf1c5C921bab457d57441',
  AIAccountabilityBondsV2: '0x6750D28865434344e04e1D0a6044394b726C3dfE',
  FlourishingMetricsOracle: '0xf7B2dC73Ec69528F171F4a0ded62da557866BaA5',
  ProductionBeliefAttestationVerifier: '0x2a46B5932e9559176241056A04a608B8fEbCc5A7',
  ERC8004ReputationRegistry: '0x98afd1440B2238D73c1394720277a6d031fCbbD0',
  ERC8004ValidationRegistry: '0x8D3495772EAcAdB7dC09F1784eF06F2D109fb8a5',
  VaultfireERC8004Adapter: '0x8bEFe7411AecddA6E1Aea8F031fedD293Ca7372E',
  MultisigGovernance: '0x34a19C7298aCA59e185F1ecfB352AC566bB4B4A9',
  PrivacyGuarantees: '0x2711AA5f1934Fe97825F02e51cB5Da58d1759625',
  MissionEnforcement: '0xBc4208A7A59af3B7E438d3308C3dc0d299d739a7',
  AntiSurveillance: '0xaaC44F1396f3F5b3C06048a1F819DC9b0f86D90c',
  BeliefAttestationVerifier: '0x32211773C8266774A704aeD471f8eF073f34bA79',
  DilithiumAttestor: '0xef703bBe9b21960ede3e96abBB0Bbd0c525Fe050',
  VaultfireTeleporterBridge: '0x62edf0cBc8Fa3d98B6A07197DFE9cb1c128a7eC7',
} as const;

// ---------------------------------------------------------------------------
// Multichain support — chain definitions
// ---------------------------------------------------------------------------

/** Metadata for a supported chain. */
export interface ChainDefinition {
  chainId: number;
  label: string;
  role: 'primary' | 'secondary' | 'testnet';
  rpcUrl: string;
  explorer: string;
}

/**
 * Registry of all chains supported by the Vaultfire Protocol.
 * Base mainnet is the canonical / primary deployment.
 */
export const SUPPORTED_CHAINS: Record<string, ChainDefinition> = {
  base: {
    chainId: 8453,
    label: 'Base Mainnet',
    role: 'primary',
    rpcUrl: 'https://mainnet.base.org',
    explorer: 'https://basescan.org',
  },
  avalanche: {
    chainId: 43114,
    label: 'Avalanche C-Chain',
    role: 'secondary',
    rpcUrl: 'https://api.avax.network/ext/bc/C/rpc',
    explorer: 'https://snowtrace.io',
  },
  avalancheFuji: {
    chainId: 43113,
    label: 'Avalanche Fuji',
    role: 'testnet',
    rpcUrl: 'https://api.avax-test.network/ext/bc/C/rpc',
    explorer: 'https://testnet.snowtrace.io',
  },
} as const;

/**
 * Deployed contract addresses for Avalanche C-Chain (Chain ID 43114).
 * All 14 contracts deployed and verified on Snowtrace — Feb 18, 2026.
 */
export const AVALANCHE_CONTRACTS: Record<string, string> = {
  ERC8004IdentityRegistry: '0x7448057C95Fb8a8B974a566cdcc9Cd042166A3f8',
  AIPartnershipBondsV2: '0xDC8447c66fE9D9c7D54607A98346A15324b7985D',
  AIAccountabilityBondsV2: '0x376831fB2457E34559891c32bEb61c442053C066',
  FlourishingMetricsOracle: '0x1437c4081233A4f0B6907dDf5374Ed610cBD6B25',
  ProductionBeliefAttestationVerifier: '0xFa8ed66E27379942cB90BB5f612F0170a5dE4924',
  ERC8004ReputationRegistry: '0x5DB1B4b412b80d03819395794fCcF5A73BF30656',
  ERC8004ValidationRegistry: '0x44f1241F5F1A76c146d580142E54590a130410B4',
  VaultfireERC8004Adapter: '0x69D3458aba750Fa85d4a25b3A23B398A3D9494fe',
  MultisigGovernance: '0x3ceA2B0853B76Ac75603C1fa2A29D96A4467Bb79',
  PrivacyGuarantees: '0x1a7391DD19Dadab89757E58F4Cf988455263533e',
  MissionEnforcement: '0xA4F4EDd4ed280Bd784650c048190fBA16e0AFd11',
  AntiSurveillance: '0x7b9293B05Bd0fcb7458d06A364078761B8E8848e',
  BeliefAttestationVerifier: '0x756bf61bF3948886a36D00ECB02CEDBdb3215c4C',
  VaultfireTeleporterBridge: '0x1762e484A48558Ea5Cd056ac2CDf43FBbA52ba58',
};

/**
 * Resolve the active chain from the VAULTFIRE_CHAIN environment variable.
 * Defaults to "base" (primary) when unset.
 */
export function resolveChain(): ChainDefinition {
  const chainKey = optionalEnv('VAULTFIRE_CHAIN', 'base');
  const chain = SUPPORTED_CHAINS[chainKey];
  if (!chain) {
    throw new Error(
      `Unsupported VAULTFIRE_CHAIN value: "${chainKey}". ` +
      `Supported: ${Object.keys(SUPPORTED_CHAINS).join(', ')}`,
    );
  }
  return chain;
}

// ---------------------------------------------------------------------------
// Demo mode configuration
// ---------------------------------------------------------------------------

/**
 * Read the current DEMO_MODE flag from the environment.
 *
 * This is a function (not a module-level constant) so that tests can set
 * process.env.DEMO_MODE *after* the module is imported and still get the
 * correct value.
 */
export function getDemoMode(): boolean {
  return boolEnv('DEMO_MODE', false);
}

/**
 * Convenience re-export — reads DEMO_MODE at call time.
 * Kept as a getter-style constant for backward compatibility with code that
 * references `DEMO_MODE` directly.
 */
export const DEMO_MODE: boolean = false; // default; use getDemoMode() at runtime

/** Number of task cycles to execute in demo mode before exiting. */
export function getDemoCycles(): number {
  return intEnv('DEMO_CYCLES', 1);
}

/** Task interval override when demo mode is active (seconds). */
export function getDemoTaskInterval(): number {
  return intEnv('DEMO_TASK_INTERVAL', 10);
}

/**
 * Returns true when the agent should run in demo mode.
 * Demo mode is only active when DEMO_MODE=true AND the chain is avalancheFuji.
 */
export function isDemoActive(): boolean {
  if (!getDemoMode()) return false;
  const chain = resolveChain();
  return chain.chainId === 43113; // avalancheFuji
}

// ---------------------------------------------------------------------------
// Agent configuration
// ---------------------------------------------------------------------------

export interface AgentConfig {
  // Wallet
  privateKey: string;
  rpcUrl: string;
  chainId: number;

  // Identity
  agentUri: string;
  agentType: string;
  agentName: string;

  // Partner
  humanPartnerAddress: string;

  // Operation
  dryRun: boolean;
  taskIntervalSeconds: number;
  logLevel: string;

  // Retry
  maxRetries: number;
  retryDelayMs: number;

  // Demo
  demoMode: boolean;
  demoCycles: number;
}

export function loadConfig(): AgentConfig {
  const chain = resolveChain();
  const demoActive = isDemoActive();

  return {
    privateKey: requireEnv('AGENT_PRIVATE_KEY'),
    rpcUrl: optionalEnv('BASE_RPC_URL', chain.rpcUrl),
    chainId: chain.chainId,

    agentUri: optionalEnv('AGENT_URI', 'https://vaultfire.io/agents/vaultfire-sentinel'),
    agentType: optionalEnv('AGENT_TYPE', 'autonomous-sentinel'),
    agentName: optionalEnv('AGENT_NAME', 'Vaultfire Sentinel'),

    humanPartnerAddress: optionalEnv(
      'HUMAN_PARTNER_ADDRESS',
      '0xfA15Ee28939B222B0448261A22156070f0A7813C',
    ),

    dryRun: boolEnv('DRY_RUN', true),
    taskIntervalSeconds: demoActive
      ? getDemoTaskInterval()
      : intEnv('TASK_INTERVAL_SECONDS', 300),
    logLevel: optionalEnv('LOG_LEVEL', 'info'),

    maxRetries: intEnv('MAX_RETRIES', 3),
    retryDelayMs: intEnv('RETRY_DELAY_MS', 5000),

    demoMode: demoActive,
    demoCycles: demoActive ? getDemoCycles() : 0,
  };
}

// ---------------------------------------------------------------------------
// Metric IDs (keccak256 hashes used by FlourishingMetricsOracle)
// ---------------------------------------------------------------------------

export const METRIC_IDS = {
  PROTOCOL_HEALTH: 'protocol_health',
  AGENT_UPTIME: 'agent_uptime',
  BOND_QUALITY: 'bond_quality',
  TASK_COMPLETION: 'task_completion',
  PARTNERSHIP_FLOURISHING: 'partnership_flourishing',
} as const;
