/**
 * Integration tests for report API (CMC, CoinGecko)
 * Uses native fetch + http server (no deprecated supertest)
 */

import { createServer } from 'http';
import express from 'express';
import reportRoutes from './report';
import { getCanonicalTokenBySymbol } from '../../config/canonical-tokens';

jest.mock('../../database/repositories/token-repo', () => ({
  TokenRepository: jest.fn().mockImplementation(() => ({
    getToken: jest.fn().mockResolvedValue(null),
  })),
}));
jest.mock('../../database/repositories/market-data-repo', () => ({
  MarketDataRepository: jest.fn().mockImplementation(() => ({
    getMarketData: jest.fn().mockImplementation(async (chainId: number, address: string) => {
      if (chainId === 138 && String(address).toLowerCase() === '0xf22258f57794cc8e06237084b353ab30fffa640b') {
        return {
          priceUsd: 1,
          volume24h: 0,
          volume7d: 0,
          volume30d: 0,
          marketCapUsd: undefined,
          liquidityUsd: 5180095723066127,
          lastUpdated: new Date('2026-05-10T01:43:11.733Z'),
        };
      }
      return null;
    }),
  })),
}));
jest.mock('../../database/repositories/pool-repo', () => ({
  PoolRepository: jest.fn().mockImplementation(() => ({
    getPoolsByToken: jest.fn().mockResolvedValue([]),
    getPoolsByChain: jest.fn().mockResolvedValue([]),
  })),
}));
jest.mock('../../indexer/cross-chain-indexer', () => ({
  buildCrossChainReport: jest.fn().mockResolvedValue({
    generatedAt: '2026-03-30T00:00:00.000Z',
    chainId: 138,
    crossChainPools: [],
    volumeByLane: [],
    atomicSwapVolume24h: 0,
    bridgeVolume24hTotal: 0,
    events: [],
  }),
}));
jest.mock('../middleware/cache');

function createApp() {
  const app = express();
  app.use('/api/v1/report', reportRoutes);
  return app;
}

async function startServer(app: express.Application): Promise<{ server: ReturnType<typeof createServer>; baseUrl: string }> {
  const server = createServer(app);
  await new Promise<void>((resolve) => server.listen(0, () => resolve()));
  const port = (server.address() as { port: number }).port;
  return { server, baseUrl: `http://127.0.0.1:${port}` };
}

describe('Report API', () => {
  let server: ReturnType<typeof createServer>;
  let baseUrl: string;

  beforeAll(async () => {
    const app = createApp();
    const started = await startServer(app);
    server = started.server;
    baseUrl = started.baseUrl;
  });

  afterAll(async () => {
    await new Promise<void>((resolve, reject) => {
      server.close((error) => {
        if (error) {
          reject(error);
          return;
        }
        resolve();
      });
    });
  });

  describe('GET /api/v1/report/cmc', () => {
    it('returns 200 with cmc format', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/cmc?chainId=138`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, unknown>;
      expect(body).toHaveProperty('generatedAt');
      expect(body).toHaveProperty('chainId', 138);
      expect(body).toHaveProperty('format', 'coinmarketcap-dex');
      expect(body).toHaveProperty('tokens');
      expect(Array.isArray(body.tokens)).toBe(true);
    });

    it('accepts chainId 651940', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/cmc?chainId=651940`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, unknown>;
      expect(body.chainId).toBe(651940);
    });

    it('enriches Mainnet cWUSDC with supply proof fields for CMC reports', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/cmc?chainId=1`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      const cwusdc = body.tokens.find((token: Record<string, any>) => token.symbol === 'cWUSDC');
      expect(cwusdc).toMatchObject({
        contract_address: '0x2de5f116bfce3d0f922d9c8351e0c5fc24b9284a',
        total_supply: 10451316981.309788,
        total_supply_raw: '10451316981309788',
        circulating_supply: 10451316981.309788,
        market_cap: 10451316981.309788,
        supply_proof_provenance: expect.objectContaining({
          status: 'ready_for_tracker_review',
        }),
      });
      expect(cwusdc.tracker_caveats).toEqual(expect.arrayContaining([expect.stringContaining('on-chain supply proof')]));
      expect(cwusdc.liquidity_usd).toBeGreaterThan(1_000_000);
      const cwusdcUsdc = cwusdc.pairs.find(
        (p: Record<string, unknown>) =>
          String(p.pair_address).toLowerCase() === '0xc28706f899266b36bc43cc072b3a921bdf2c48d9'
      );
      expect(cwusdcUsdc?.liquidity_usd).toBeGreaterThan(1_000_000);
    });
  });

  describe('GET /api/v1/report/coingecko', () => {
    it('returns 200 with coingecko format', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/coingecko?chainId=138`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, unknown>;
      expect(body).toHaveProperty('generatedAt');
      expect(body).toHaveProperty('chainId', 138);
      expect(body).toHaveProperty('format', 'coingecko-submission');
      expect(body).toHaveProperty('tokens');
      expect(Array.isArray(body.tokens)).toBe(true);
    });

    it('enriches Mainnet cWUSDC with supply proof, circulating supply, and market cap', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/coingecko?chainId=1`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      const cwusdc = body.tokens.find((token: Record<string, any>) => token.symbol === 'cWUSDC');
      expect(cwusdc).toMatchObject({
        contract_address: '0x2de5f116bfce3d0f922d9c8351e0c5fc24b9284a',
        total_supply: 10451316981.309788,
        total_supply_raw: '10451316981309788',
        circulating_supply: 10451316981.309788,
        circulating_supply_formula: 'circulatingSupply = totalSupply - protocolControlledNonCirculatingBalances',
        supply_proof_provenance: expect.objectContaining({
          schema: 'mainnet-cwusdc-supply-proof/v1',
          referenceBlock: 25047586,
        }),
        market_data: expect.objectContaining({
          current_price: { usd: 1 },
          market_cap: 10451316981.309788,
          liquidity_usd: expect.any(Number),
        }),
      });
      expect(cwusdc.market_data.liquidity_usd).toBeGreaterThan(1_000_000);
      expect(cwusdc.tracker_caveats).toEqual(expect.arrayContaining([expect.stringContaining('No public tracker')]));
    });

    it('surfaces GRU v2 deployment-status pools in tracker-facing token reports', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/coingecko?chainId=1`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      const cwusdc = body.tokens.find((token: Record<string, any>) => token.symbol === 'cWUSDC');
      expect(cwusdc.liquidity_pools).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            pool_address: '0x69776fc607e9eda8042e320e7e43f54d06c68f0e',
            source: 'gru-v2-deployment-status',
            status: 'live',
            role: 'defense',
          }),
        ])
      );
    });

    it('surfaces catalog-backed supply proof for Mainnet GRU assets with circulating review caveats', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/coingecko?chainId=1`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      const cwusdt = body.tokens.find((token: Record<string, any>) => token.symbol === 'cWUSDT');
      expect(cwusdt).toMatchObject({
        contract_address: '0xaf5017d0163ecb99d9b5d94e3b4d7b09af44d8ae',
        supply_proof_provenance: {
          source: 'repo-supply-proof-catalog',
          status: 'onchain_total_supply_proved_circulating_review_required',
        },
      });
      expect(cwusdt.total_supply).toBeTruthy();
      expect(cwusdt.tracker_caveats?.length).toBeGreaterThan(0);
    });
  });

  describe('GET /api/v1/report/token-price/:symbol', () => {
    it('returns a compact cWUSDC price evidence packet for reviewers', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/token-price/cWUSDC?chainId=1`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;

      expect(body).toMatchObject({
        schema: 'dbis-token-price-evidence/v1',
        chainId: 1,
        token: {
          address: '0x2de5f116bfce3d0f922d9c8351e0c5fc24b9284a',
          symbol: 'cWUSDC',
          decimals: 6,
        },
        price: {
          usd: 1,
          source: 'token-aggregation',
        },
        supply: {
          totalSupply: 10451316981.309788,
          totalSupplyRaw: '10451316981309788',
          circulatingSupply: 10451316981.309788,
          proof: expect.objectContaining({
            schema: 'mainnet-cwusdc-supply-proof/v1',
          }),
        },
        valuation: {
          marketCapUsd: 10451316981.309788,
        },
        submissionLinks: {
          coingeckoReport: expect.stringContaining('/api/v1/report/coingecko?chainId=1'),
          cmcReport: expect.stringContaining('/api/v1/report/cmc?chainId=1'),
          tokenList: expect.stringContaining('/api/v1/report/token-list?chainId=1'),
          etherscan: 'https://etherscan.io/token/0x2de5f116bfce3d0f922d9c8351e0c5fc24b9284a',
        },
      });
      expect(body.price.caveat).toContain('Etherscan USD Value');
      expect(Array.isArray(body.pools)).toBe(true);
    });

    it('normalizes raw 6-decimal Chain 138 liquidity in compact price evidence', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/token-price/cUSDC?chainId=138`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;

      expect(body).toMatchObject({
        chainId: 138,
        token: {
          symbol: 'cUSDC',
          decimals: 6,
        },
        price: {
          usd: 1,
        },
      });
      expect(body.valuation.liquidityUsd).toBeLessThan(38601011267);
      expect(body.valuation.liquidityUsd).toBeCloseTo(5180095723.066127, 6);
    });

    it('returns 404 for an unknown token symbol', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/token-price/NOPE?chainId=1`);
      expect(res.status).toBe(404);
    });
  });

  describe('GET /api/v1/report/all', () => {
    it('includes GRU transport summary for operator visibility', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/all?chainId=138`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      expect(body.gruTransport?.system?.name).toBe('GRU Monetary Transport Layer');
      expect(body.gruTransport?.summary).toMatchObject({
        transportPairs: expect.any(Number),
        runtimeReadyTransportPairs: expect.any(Number),
      });
      expect(body.gruTransport?.gasAssetFamilies).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            familyKey: 'eth_l2',
            backingMode: 'hybrid_cap',
          }),
        ])
      );
    });

    it('fills canonical fallback usd pricing when market data is absent', async () => {
      const weth = getCanonicalTokenBySymbol(138, 'WETH');
      expect(weth?.addresses[138]).toBeTruthy();
      const wethAddress = String(weth?.addresses[138]).toLowerCase();

      const res = await fetch(`${baseUrl}/api/v1/report/all?chainId=138`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      const tokens138 = body.tokens?.['138'];
      expect(Array.isArray(tokens138)).toBe(true);

      const wethEntry = tokens138.find((token: Record<string, any>) => token.address === wethAddress);
      expect(wethEntry).toMatchObject({
        symbol: 'WETH',
        decimals: 18,
        market: expect.objectContaining({
          priceUsd: 2490,
          volume24h: 0,
          liquidityUsd: 0,
          lastUpdated: '2026-04-15T00:00:00.000Z',
        }),
      });
    });

    it('includes Mainnet cWUSDC supply proof enrichment in unified reports', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/all?chainId=1`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      const cwusdc = body.tokens?.['1']?.find((token: Record<string, any>) => token.symbol === 'cWUSDC');
      expect(cwusdc).toMatchObject({
        totalSupply: '10451316981.309788',
        totalSupplyRaw: '10451316981309788',
        circulatingSupply: '10451316981.309788',
        circulatingSupplyFormula: 'circulatingSupply = totalSupply - protocolControlledNonCirculatingBalances',
        market: expect.objectContaining({
          priceUsd: 1,
          marketCapUsd: 10451316981.309788,
        }),
        supplyProofProvenance: expect.objectContaining({
          schema: 'mainnet-cwusdc-supply-proof/v1',
          referenceBlock: 25047586,
        }),
      });
    });

    it('distinguishes proof-gated Mainnet cW assets from deterministic placeholder bindings', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/all?chainId=1`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      const catalogProved = body.tokens?.['1']?.find((entry: Record<string, any>) => entry.symbol === 'cWUSDT');
      expect(catalogProved).toMatchObject({
        supplyProofProvenance: {
          source: 'repo-supply-proof-catalog',
          status: 'onchain_total_supply_proved_circulating_review_required',
        },
      });
      expect(catalogProved.totalSupply).toBeTruthy();
      expect(catalogProved.trackerCaveats?.length).toBeGreaterThan(0);

      const placeholderSymbols = ['cWBTC', 'cWETH'];
      for (const symbol of placeholderSymbols) {
        const token = body.tokens?.['1']?.find((entry: Record<string, any>) => entry.symbol === symbol);
        expect(token).toMatchObject({
          supplyProofProvenance: {
            source: 'deterministic-placeholder-address',
            status: 'non_reportable_until_erc20_deployed',
          },
        });
        expect(token.totalSupply).toBeUndefined();
        expect(token.trackerCaveats).toEqual(expect.arrayContaining([expect.stringContaining('deterministic placeholder')]));
      }
    });

    it('marks base GRU c assets with catalog supply proof instead of leaving silent supply fields', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/all?chainId=138`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      const cusdc = body.tokens?.['138']?.find((entry: Record<string, any>) => entry.symbol === 'cUSDC');
      expect(cusdc).toMatchObject({
        type: 'base',
        registryFamily: 'iso4217',
        supplyProofProvenance: {
          source: 'repo-supply-proof-catalog',
          status: 'onchain_total_supply_proved_circulating_review_required',
        },
      });
      expect(cusdc.totalSupply).toBeTruthy();
      expect(cusdc.trackerCaveats?.length).toBeGreaterThan(0);
    });
  });

  describe('GET /api/v1/report/gas-registry', () => {
    it('returns both chain summaries and runtime pairs for gas rollout consumers', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/gas-registry`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      expect(body.gasAssetFamilies).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            familyKey: 'eth_mainnet',
          }),
        ])
      );
      expect(body.runtimePairs).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            key: '138-1-cETH-cWETH',
            familyKey: 'eth_mainnet',
            destinationChainId: 1,
            destinationChainName: 'Ethereum Mainnet',
            wrappedNativeQuoteSymbol: 'WETH',
            stableQuoteSymbol: 'USDC',
          }),
        ])
      );
      expect(body.chains).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            chainId: 1,
          }),
        ])
      );
    });
  });

  describe('GET /api/v1/report/adoption-readiness', () => {
    it('summarizes proved, proof-gated, pool-indexed, and scoring gates', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/adoption-readiness`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      expect(body.scope).toBe('gru-c-and-cw-assets');
      expect(body.counts).toMatchObject({
        candidates: expect.any(Number),
        reportableCandidates: expect.any(Number),
        nonReportablePlaceholder: expect.any(Number),
        proved: expect.any(Number),
        proofRequired: expect.any(Number),
        silent: 0,
        liquidityMissing: expect.any(Number),
        liquidityMissingWithPools: expect.any(Number),
        liquidityMissingWithoutPools: expect.any(Number),
        gruV2PoolsWithStatus: expect.any(Number),
      });
      expect(body.institutional.score).toEqual(expect.any(Number));
      expect(body.cryptoListing.score).toEqual(expect.any(Number));
      expect(Array.isArray(body.blockerInventory.proofRequiredByChain)).toBe(true);
      expect(Array.isArray(body.blockerInventory.liquidityMissingByChain)).toBe(true);
      expect(Array.isArray(body.blockerInventory.liquidityMissingWithPoolsByChain)).toBe(true);
      expect(Array.isArray(body.blockerInventory.liquidityMissingWithoutPoolsByChain)).toBe(true);
      expect(Array.isArray(body.blockerInventory.liquidityMissingDetails)).toBe(true);
      expect(Array.isArray(body.blockerInventory.externalOfficialQuoteLiquidityByChain)).toBe(true);
      expect(Array.isArray(body.blockerInventory.nonReportablePlaceholderByChain)).toBe(true);
      expect(Array.isArray(body.blockerInventory.gruV2PoolsMissingStatus)).toBe(true);
      expect(Array.isArray(body.blockerInventory.notes)).toBe(true);
    });

    it('does not treat external official USDC/USDT mirrors as GRU liquidity blockers', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/adoption-readiness`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      expect(body.counts.externalOfficialQuoteLiquidity).toBeGreaterThan(0);
      expect(body.blockerInventory.externalOfficialQuoteLiquidityByChain).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            chainId: 1,
            symbols: expect.arrayContaining(['cUSDC', 'cUSDT']),
          }),
          expect.objectContaining({
            chainId: 56,
            symbols: expect.arrayContaining(['cUSDC', 'cUSDT']),
          }),
        ])
      );
      expect(body.blockerInventory.liquidityMissingDetails).not.toEqual(
        expect.arrayContaining([
          expect.objectContaining({ chainId: 1, symbol: 'cUSDT' }),
          expect.objectContaining({ chainId: 56, symbol: 'cUSDC' }),
        ])
      );
    });
  });

  describe('GET /api/v1/report/token-list', () => {
    it('surfaces both V1 and V2 Chain 138 canonical GRU deployments explicitly', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/token-list?chainId=138`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      expect(body.tokens).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            symbol: 'cUSDT',
            chainId: 138,
          }),
          expect.objectContaining({
            symbol: 'cUSDT_V2',
            chainId: 138,
            extensions: expect.objectContaining({
              familySymbol: 'cUSDT',
              deploymentVersion: 'v2',
              preferredForX402: true,
            }),
          }),
          expect.objectContaining({
            symbol: 'cUSDC',
            chainId: 138,
          }),
          expect.objectContaining({
            symbol: 'cUSDC_V2',
            chainId: 138,
            extensions: expect.objectContaining({
              familySymbol: 'cUSDC',
              deploymentVersion: 'v2',
              preferredForX402: true,
            }),
          }),
        ])
      );
    });

    it('surfaces the cUSDW hub asset on Chain 138 and cWUSDW on active edge chains', async () => {
      const chain138Res = await fetch(`${baseUrl}/api/v1/report/token-list?chainId=138`);
      expect(chain138Res.status).toBe(200);
      const chain138Body = (await chain138Res.json()) as Record<string, any>;
      expect(chain138Body.tokens).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            symbol: 'cUSDW',
            chainId: 138,
          }),
        ])
      );

      const bscRes = await fetch(`${baseUrl}/api/v1/report/token-list?chainId=56`);
      expect(bscRes.status).toBe(200);
      const bscBody = (await bscRes.json()) as Record<string, any>;
      expect(bscBody.tokens).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            symbol: 'cWUSDW',
            chainId: 56,
          }),
        ])
      );
    });

    it('surfaces cAUSDT on Chain 138 when configured and cWAUSDT on active edge chains', async () => {
      const chain138Res = await fetch(`${baseUrl}/api/v1/report/token-list?chainId=138`);
      expect(chain138Res.status).toBe(200);
      const chain138Body = (await chain138Res.json()) as Record<string, any>;
      expect(chain138Body.tokens).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            symbol: 'cAUSDT',
            chainId: 138,
          }),
        ])
      );

      const bscRes = await fetch(`${baseUrl}/api/v1/report/token-list?chainId=56`);
      expect(bscRes.status).toBe(200);
      const bscBody = (await bscRes.json()) as Record<string, any>;
      expect(bscBody.tokens).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            symbol: 'cWAUSDT',
            chainId: 56,
          }),
        ])
      );

      const polygonRes = await fetch(`${baseUrl}/api/v1/report/token-list?chainId=137`);
      expect(polygonRes.status).toBe(200);
      const polygonBody = (await polygonRes.json()) as Record<string, any>;
      expect(polygonBody.tokens).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            symbol: 'cWAUSDT',
            chainId: 137,
          }),
        ])
      );

      const avalancheRes = await fetch(`${baseUrl}/api/v1/report/token-list?chainId=43114`);
      expect(avalancheRes.status).toBe(200);
      const avalancheBody = (await avalancheRes.json()) as Record<string, any>;
      expect(avalancheBody.tokens).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            symbol: 'cWAUSDT',
            chainId: 43114,
          }),
        ])
      );

      const celoRes = await fetch(`${baseUrl}/api/v1/report/token-list?chainId=42220`);
      expect(celoRes.status).toBe(200);
      const celoBody = (await celoRes.json()) as Record<string, any>;
      expect(celoBody.tokens).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            symbol: 'cWAUSDT',
            chainId: 42220,
          }),
        ])
      );
    });

    it('excludes deterministic gas placeholders from wallet-facing token list', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/token-list?chainId=138&wallet=1`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      const symbols = body.tokens.map((token: Record<string, any>) => token.symbol);
      const placeholderSymbols = ['cAVAX', 'cBNB', 'cETH', 'cETHL2', 'cPOL', 'cCRO', 'cXDAI', 'cCELO', 'cWEMIX'];
      for (const symbol of placeholderSymbols) {
        expect(symbols).not.toContain(symbol);
      }
      expect(symbols).toEqual(
        expect.arrayContaining(['cUSDT', 'cUSDC', 'cBTC', 'WETH'])
      );
    });

    it('surfaces cBTC on Chain 138 and cWBTC on the staged public mesh with monetary-unit metadata', async () => {
      const chain138Res = await fetch(`${baseUrl}/api/v1/report/token-list?chainId=138`);
      expect(chain138Res.status).toBe(200);
      const chain138Body = (await chain138Res.json()) as Record<string, any>;
      expect(chain138Body.tokens).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            symbol: 'cBTC',
            chainId: 138,
            extensions: expect.objectContaining({
              registryFamily: 'monetary_unit',
            }),
          }),
        ])
      );

      const mainnetRes = await fetch(`${baseUrl}/api/v1/report/token-list?chainId=1`);
      expect(mainnetRes.status).toBe(200);
      const mainnetBody = (await mainnetRes.json()) as Record<string, any>;
      expect(mainnetBody.tokens).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            symbol: 'cWBTC',
            chainId: 1,
            extensions: expect.objectContaining({
              registryFamily: 'monetary_unit',
            }),
          }),
        ])
      );
    });

    it('surfaces gas-native canonicals on Chain 138 and mirrored cW gas tokens on their public lanes', async () => {
      const chain138Res = await fetch(`${baseUrl}/api/v1/report/token-list?chainId=138`);
      expect(chain138Res.status).toBe(200);
      const chain138Body = (await chain138Res.json()) as Record<string, any>;
      expect(chain138Body.tokens).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            symbol: 'cETH',
            chainId: 138,
            extensions: expect.objectContaining({
              registryFamily: 'gas_native',
              walletWatchEligible: false,
            }),
          }),
          expect.objectContaining({
            symbol: 'cETHL2',
            chainId: 138,
            extensions: expect.objectContaining({
              registryFamily: 'gas_native',
              walletWatchEligible: false,
            }),
          }),
        ])
      );

      const optimismRes = await fetch(`${baseUrl}/api/v1/report/token-list?chainId=10`);
      expect(optimismRes.status).toBe(200);
      const optimismBody = (await optimismRes.json()) as Record<string, any>;
      expect(optimismBody.tokens).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            symbol: 'cWETHL2',
            chainId: 10,
            extensions: expect.objectContaining({
              registryFamily: 'gas_native',
            }),
          }),
        ])
      );

      const mainnetRes = await fetch(`${baseUrl}/api/v1/report/token-list?chainId=1`);
      expect(mainnetRes.status).toBe(200);
      const mainnetBody = (await mainnetRes.json()) as Record<string, any>;
      expect(mainnetBody.tokens).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            symbol: 'cWETH',
            chainId: 1,
            extensions: expect.objectContaining({
              registryFamily: 'gas_native',
            }),
          }),
        ])
      );
    });

    it('uses packaged DBIS-level local logo assets while preserving original logo references', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/token-list?chainId=1`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      const cwusdc = body.tokens.find((token: Record<string, any>) => token.symbol === 'cWUSDC');
      expect(cwusdc).toMatchObject({
        name: 'Wrapped cUSDC',
        address: '0x2de5F116bFcE3d0f922d9C8351e0c5Fc24b9284a',
        logoURI: 'https://d-bis.org/tokens/cwusdc.svg',
        extensions: expect.objectContaining({
          originalLogoURI: 'https://d-bis.org/tokens/cwusdc.svg',
        }),
      });
    });

    it('returns Uniswap token list schema fields for mainnet lists', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/token-list?chainId=1`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      expect(body.name).toBe('DBIS Ethereum Mainnet GRU');
      expect(body.version).toEqual({ major: 1, minor: 0, patch: 0 });
      expect(body.tokens[0]).not.toHaveProperty('type');
    });

    it('serves the pinned static ethereum-mainnet token list', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/token-list/static/ethereum-mainnet`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      expect(body.name).toBe('DBIS Ethereum Mainnet GRU');
      expect(body.version).toEqual({ major: 1, minor: 1, patch: 0 });
      expect(body.tokens).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            symbol: 'cWUSDC',
            name: 'Wrapped cUSDC',
            address: '0x2de5F116bFcE3d0f922d9C8351e0c5Fc24b9284a',
          }),
        ])
      );
    });
  });

  describe('GET /api/v1/report/cw-registry', () => {
    it('reads the live cW registry from deployment-status json when available', async () => {
      const previousPath = process.env.DEPLOYMENT_STATUS_JSON_PATH;
      const tempPath = `/tmp/token-aggregation-cw-registry-${Date.now()}.json`;

      process.env.DEPLOYMENT_STATUS_JSON_PATH = tempPath;
      await import('fs/promises').then((fs) =>
        fs.writeFile(
          tempPath,
          JSON.stringify(
            {
              version: 'test-1',
              updated: '2026-04-04',
              chains: {
                '56': {
                  name: 'BSC',
                  cwTokens: {
                    cWAUSDT: '0xe1a51Bc037a79AB36767561B147eb41780124934',
                  },
                },
              },
            },
            null,
            2
          )
        )
      );

      try {
        const res = await fetch(`${baseUrl}/api/v1/report/cw-registry?chainId=56`);
        expect(res.status).toBe(200);
        const body = (await res.json()) as Record<string, any>;
        expect(body.source).toBe('deployment-status-file');
        expect(body.complete).toBe(true);
        expect(body.version).toBe('test-1');
        expect(body.chains).toEqual([
          expect.objectContaining({
            chainId: 56,
            name: 'BSC',
            tokens: [
              expect.objectContaining({
                symbol: 'cWAUSDT',
              }),
            ],
          }),
        ]);
      } finally {
        await import('fs/promises').then((fs) => fs.unlink(tempPath).catch(() => undefined));
        if (previousPath === undefined) {
          delete process.env.DEPLOYMENT_STATUS_JSON_PATH;
        } else {
          process.env.DEPLOYMENT_STATUS_JSON_PATH = previousPath;
        }
      }
    });
  });

  describe('GET /api/v1/report/gru-v2-pmm-pools', () => {
    it('returns resolved PMM pools from deployment-status when file is set', async () => {
      const previousPath = process.env.DEPLOYMENT_STATUS_JSON_PATH;
      const tempPath = `/tmp/token-aggregation-gru-v2-pmm-${Date.now()}.json`;

      process.env.DEPLOYMENT_STATUS_JSON_PATH = tempPath;
      await import('fs/promises').then((fs) =>
        fs.writeFile(
          tempPath,
          JSON.stringify(
            {
              version: 'test-gru-pools',
              updated: '2026-04-18',
              homeChainId: 138,
              chains: {
                '1': {
                  name: 'Ethereum Mainnet',
                  cwTokens: { cWUSDT: '0xaf5017d0163ecb99d9b5d94e3b4d7b09af44d8ae' },
                  anchorAddresses: { USDC: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' },
                  pmmPools: [
                    {
                      base: 'cWUSDT',
                      quote: 'USDC',
                      poolAddress: '0x1111111111111111111111111111111111111111',
                      feeBps: 3,
                      role: 'public_routing',
                      publicRoutingEnabled: true,
                    },
                  ],
                },
              },
            },
            null,
            2
          )
        )
      );

      try {
        const res = await fetch(`${baseUrl}/api/v1/report/gru-v2-pmm-pools?chainId=1`);
        expect(res.status).toBe(200);
        const body = (await res.json()) as Record<string, unknown>;
        expect(body.source).toBe('deployment-status-file');
        expect(body.complete).toBe(true);
        expect(body.version).toBe('test-gru-pools');
        expect(Array.isArray(body.pools)).toBe(true);
        expect((body.pools as unknown[]).length).toBeGreaterThanOrEqual(1);
        expect((body.pools as Array<{ poolAddress: string }>)[0]).toMatchObject({
          poolAddress: '0x1111111111111111111111111111111111111111',
          section: 'pmmPools',
          status: 'routing_enabled',
          statusReason: expect.stringContaining('public routing is enabled'),
        });
        expect(body.lifecycle).toMatchObject({
          routingEnabled: 1,
          routeVisible: 1,
        });
      } finally {
        await import('fs/promises').then((fs) => fs.unlink(tempPath).catch(() => undefined));
        if (previousPath === undefined) {
          delete process.env.DEPLOYMENT_STATUS_JSON_PATH;
        } else {
          process.env.DEPLOYMENT_STATUS_JSON_PATH = previousPath;
        }
      }
    });
  });

  describe('GET /api/v1/report/pool-registry', () => {
    it('returns curated DODO and UniV2 pool registry', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/pool-registry?chainId=138`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, unknown>;
      expect(Array.isArray(body.pools)).toBe(true);
      expect(typeof body.count).toBe('number');
      expect(body.chain138StackAIntegration).toBe('0x86ADA6Ef91A3B450F89f2b751e93B1b7A3218895');
      const pools = body.pools as Array<{ lpTokenType?: string; venue?: string }>;
      if (pools.length > 0) {
        expect(['dodo_dvm', 'univ2_pair']).toContain(pools[0].lpTokenType);
      }
    });
  });

  describe('GET /api/v1/report/external-indexer-readiness', () => {
    it('returns tracker-facing readiness and source endpoints', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/external-indexer-readiness?chainId=138`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      expect(body.schema).toBe('dbis-external-indexer-readiness/v1');
      expect(body.chainId).toBe(138);
      expect(body.summary.tokenCount).toBeGreaterThan(0);
      expect(body.endpoints.coingecko).toContain('/api/v1/report/coingecko?chainId=138');
      expect(body.trackers.defiLlama.status).toBe('merged_chain_listed_tvl_pending_server_pricing');
      expect(body.trackers.coinGecko).toHaveProperty('readyFromDbisSide');
      expect(body.trackers.coinMarketCap).toHaveProperty('readyFromDbisSide');
      expect(body.trackers.dexScreener.status).toBe('chain_indexing_external_pending');
    });
  });

  describe('GET /api/v1/report/gas-registry', () => {
    it('reads the live gas rollout registry from deployment-status json when available', async () => {
      const res = await fetch(`${baseUrl}/api/v1/report/gas-registry?chainId=10`);
      expect(res.status).toBe(200);
      const body = (await res.json()) as Record<string, any>;
      expect(body.source).toBe('deployment-status-file');
      expect(body.gasAssetFamilies).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            familyKey: 'eth_l2',
            backingMode: 'hybrid_cap',
          }),
        ])
      );
      expect(body.chains).toEqual([
        expect.objectContaining({
          chainId: 10,
          families: [
            expect.objectContaining({
              familyKey: 'eth_l2',
              mirroredSymbol: 'cWETHL2',
              dodoPmm: expect.arrayContaining([
                expect.objectContaining({
                  quote: 'WETH',
                }),
              ]),
            }),
          ],
        }),
      ]);
    });
  });
});
