import {
  NON_EVM_RELAY_LIFECYCLE,
  type NonEvmNetworkPolicy,
  type NonEvmRelayObservation
} from '../../non-evm-relay/lifecycle';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

export const SOLANA_RELAY_POLICY: NonEvmNetworkPolicy = {
  identifier: 'Solana',
  relayMode: 'custom_relay',
  destinationProgramModel: 'spl_or_bridge_wrapped_cw',
  signerFundingPolicy: 'sol_operator_signer',
  finalityPolicy: 'slot_finality>=32',
  publicExposureStatus: 'live'
};

export interface SolanaRelayAssetRuntime {
  chain138Symbol: string;
  sourceToken: string;
  solanaSymbol: string;
  solanaMint: string;
  decimals: number;
  smokeTestAmountRaw: string;
}

export interface SolanaRelayRuntimeConfig {
  sourceChain: {
    chainId: number;
    chainRegistryAddress: string;
    registryIdentifier: string;
    adapterAddress: string | null;
  };
  solana: {
    cluster: string;
    rpcUrl: string;
    operatorWallet: string;
    confirmationFinality: number;
    recipientEncoding: string;
  };
  relay: {
    mode: string;
    runtimeConfigEnv: string;
    syntheticConfirmationPrefix: string;
    publicExposureStatus?: string;
    workerEntryPoint?: string;
  };
  smokeTests: {
    defaultAssets: string[];
    wethRawAmount: string;
    gruRawAmount: string;
    requireAdapterRegistration: boolean;
  };
  assets: SolanaRelayAssetRuntime[];
}

export function resolveSolanaRelayRuntimeConfigPath(): string {
  const explicit = process.env.SOLANA_RELAY_RUNTIME_CONFIG;
  if (explicit && explicit.trim() !== '') {
    return path.resolve(process.cwd(), explicit);
  }

  return path.resolve(__dirname, '../../../../config/solana-relay-runtime.json');
}

export function loadSolanaRelayRuntimeConfig(): SolanaRelayRuntimeConfig {
  const runtimePath = resolveSolanaRelayRuntimeConfigPath();
  const raw = fs.readFileSync(runtimePath, 'utf8');
  return JSON.parse(raw) as SolanaRelayRuntimeConfig;
}

/**
 * Shared lifecycle surface for the Solana relay worker.
 * The actual host-side worker entry point lives in relay-worker.mjs and performs
 * real Solana settlement plus Chain 138 finalization.
 */
export class SolanaRelayService {
  readonly lifecycle = NON_EVM_RELAY_LIFECYCLE;
  readonly runtime: SolanaRelayRuntimeConfig;

  constructor(runtime = loadSolanaRelayRuntimeConfig()) {
    this.runtime = runtime;
  }

  recordObservation(observation: NonEvmRelayObservation): NonEvmRelayObservation {
    return {
      ...observation,
      lifecycleStep: observation.lifecycleStep
    };
  }

  getAsset(symbol: string): SolanaRelayAssetRuntime | undefined {
    return this.runtime.assets.find((asset) => asset.solanaSymbol === symbol || asset.chain138Symbol === symbol);
  }

  buildSmokeObservation(
    requestId: string,
    symbol: string,
    destinationReference?: string
  ): NonEvmRelayObservation {
    const asset = this.getAsset(symbol);
    const destination = destinationReference || asset?.solanaMint || this.runtime.solana.operatorWallet;

    return {
      requestId,
      lifecycleStep: 'confirm_finalize',
      destinationReference: destination,
      fulfillmentId: `${this.runtime.relay.syntheticConfirmationPrefix}:${symbol}:${requestId}`,
      finalityValue: this.runtime.solana.confirmationFinality,
      replayRejected: false
    };
  }
}
