import assert from "node:assert/strict";
import { describe, it } from "node:test";

import {
  webExtract,
  webResearch,
  webSearch,
} from "../geminiWebResearchTools.ts";

function htmlResponse(body: string): Response {
  return new Response(body, {
    status: 200,
    headers: { "content-type": "text/html; charset=utf-8" },
  });
}

describe("geminiWebResearchTools", () => {
  it("webSearch returns real source URLs from DuckDuckGo HTML", async () => {
    const mockFetch: typeof fetch = async () => htmlResponse(`
      <div class="result">
        <a class="result__a" href="//duckduckgo.com/l/?uddg=https%3A%2F%2Fexample.com%2Fguide">Example Guide</a>
        <a class="result__snippet">A useful source about the topic.</a>
      </div>
    `);
    const result = await webSearch({ query: "example topic", limit: 3 }, mockFetch);
    const rows = result.results as Array<Record<string, unknown>>;
    assert.equal(rows.length, 1);
    assert.equal(rows[0]?.source_url, "https://example.com/guide");
    assert.equal(rows[0]?.title, "Example Guide");
    assert.match(String(rows[0]?.snippet), /useful source/);
  });

  it("webExtract extracts readable text and tables with source_url", async () => {
    const mockFetch: typeof fetch = async () => htmlResponse(`
      <html><head><title>Quarterly Results</title></head><body>
        <main><h1>Results</h1><p>Revenue increased by 20 percent.</p>
          <table><tr><th>Quarter</th><th>Revenue</th></tr><tr><td>Q1</td><td>120</td></tr></table>
        </main>
      </body></html>
    `);
    const result = await webExtract({ url: "https://example.com/results", min_content_chars: 20 }, mockFetch);
    assert.equal(result.source_url, "https://example.com/results");
    assert.match(result.content, /Revenue increased/);
    assert.deepEqual(result.tables[0]?.columns, ["Quarter", "Revenue"]);
    assert.deepEqual(result.tables[0]?.rows, [["Q1", "120"]]);
    assert.equal(result.tables[0]?.source_url, "https://example.com/results");
    assert.equal(result.quality.passed, true);
    assert.equal(result.quality.table_count, 1);
  });

  it("webResearch searches, extracts, and emits a sourced report", async () => {
    const mockFetch: typeof fetch = async (input) => {
      const url = String(input);
      if (url.includes("duckduckgo.com")) {
        return htmlResponse(`
          <a class="result__a" href="https://example.com/source-a">Source A</a>
          <a class="result__snippet">Evidence A</a>
          <a class="result__a" href="https://example.org/source-b">Source B</a>
          <a class="result__snippet">Evidence B</a>
        `);
      }
      return htmlResponse(`<html><head><title>${url}</title></head><body><main><p>Verified evidence from ${url}</p></main></body></html>`);
    };
    const result = await webResearch(
      { question: "What is verified?", max_sources: 2 },
      mockFetch,
    );
    assert.deepEqual(result.source_urls, [
      "https://example.com/source-a",
      "https://example.org/source-b",
    ]);
    assert.match(String(result.report_markdown), /Source: https:\/\/example\.com\/source-a/);
    assert.match(String(result.report_markdown), /## Sources/);
  });

  it("webExtract rejects local and private URLs", async () => {
    await assert.rejects(
      () => webExtract({ url: "http://127.0.0.1/admin" }),
      /Private or local URLs are not allowed/,
    );
    await assert.rejects(
      () => webExtract({ url: "http://192.168.1.5/" }),
      /Private or local URLs are not allowed/,
    );
  });

  it("webExtract enforces explicit quality requirements", async () => {
    const mockFetch: typeof fetch = async () => htmlResponse("<html><body><main>short page</main></body></html>");
    await assert.rejects(
      () => webExtract({
        url: "https://example.com/weak",
        required_texts: ["Expected Model"],
        min_content_chars: 500,
        min_tables: 1,
        fail_on_quality: true,
      }, mockFetch),
      /WEB_EXTRACT_QUALITY_FAILED/,
    );
  });
});
