#!/usr/bin/env node

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const API_KEY = process.env.BREHON_API_KEY || "";
const BASE_URL = (
  process.env.BREHON_API_BASE_URL || "https://api.brehon.dev/api/v1"
).replace(/\/+$/, "");

// ── HTTP helper ──────────────────────────────────────────────

async function request(method, path, { params, body } = {}) {
  if (!API_KEY) {
    return {
      error: true,
      detail:
        "BREHON_API_KEY environment variable is not set. Get a free key at https://brehon.dev",
    };
  }

  let url = `${BASE_URL}${path}`;
  if (params) {
    const qs = new URLSearchParams(params).toString();
    if (qs) url += `?${qs}`;
  }

  try {
    const resp = await fetch(url, {
      method,
      headers: {
        Authorization: `Bearer ${API_KEY}`,
        "Content-Type": "application/json",
        "User-Agent": "brehon-mcp-server/1.0.0",
      },
      ...(body !== undefined ? { body: JSON.stringify(body) } : {}),
    });

    const data = await resp.json();
    if (!resp.ok) {
      return {
        error: true,
        status_code: resp.status,
        detail: data.detail || `HTTP ${resp.status}`,
      };
    }
    return data;
  } catch (err) {
    return { error: true, detail: "Request failed — check your API key and network connection" };
  }
}

function json(data) {
  return JSON.stringify(data, null, 2);
}

// ── Server ───────────────────────────────────────────────────

const server = new McpServer({
  name: "Brehon Privacy API",
  version: "1.0.0",
});

// ── Tools ────────────────────────────────────────────────────

server.registerTool("search_privacy_laws", {
  description:
    "Search and filter privacy laws by type, jurisdiction, or geographic scope. All parameters are optional. Returns a list of matching privacy law summaries. Example law_type values: gdpr, pipeda, ccpa, cpra.",
  inputSchema: {
    law_type: z.string().optional().describe("Filter by law type (e.g. gdpr, ccpa, pipeda)"),
    jurisdiction: z.string().optional().describe("Filter by jurisdiction (e.g. European Union, California)"),
    geographic_scope: z.string().optional().describe("Filter by geographic scope"),
    sub_type: z.string().optional().describe("Filter by sub-type"),
  },
}, async ({ law_type, jurisdiction, geographic_scope, sub_type }) => {
  const params = {};
  if (law_type) params.law_type = law_type;
  if (jurisdiction) params.jurisdiction = jurisdiction;
  if (geographic_scope) params.geographic_scope = geographic_scope;
  if (sub_type) params.sub_type = sub_type;
  const result = await request("GET", "/privacy-laws", { params });
  return { content: [{ type: "text", text: json(result) }] };
});

server.registerTool("get_privacy_law_details", {
  description:
    "Get full details for a specific privacy law by its ID. Example IDs: gdpr-eu, ccpa-ca-us, pipeda-ca, lgpd-br-2018. Returns the complete law record including rights, penalties, legal bases, key principles, and exemptions — each with a legal_reference citing the specific statutory article or section.",
  inputSchema: {
    law_id: z.string().describe("The law ID (e.g. gdpr-eu, ccpa-ca-us)"),
  },
}, async ({ law_id }) => {
  const result = await request("GET", `/privacy-laws/${encodeURIComponent(law_id)}`);
  return { content: [{ type: "text", text: json(result) }] };
});

server.registerTool("get_data_subject_rights", {
  description:
    "Get data subject rights granted by a specific privacy law. Returns the list of rights (e.g. right to access, right to erasure) with descriptions, conditions, and legal_reference (statutory citation).",
  inputSchema: {
    law_id: z.string().describe("The law ID (e.g. gdpr-eu, ccpa-ca-us)"),
  },
}, async ({ law_id }) => {
  const result = await request("GET", `/privacy-laws/${encodeURIComponent(law_id)}/rights`);
  return { content: [{ type: "text", text: json(result) }] };
});

server.registerTool("get_legal_bases", {
  description:
    "Get the legal bases for data processing under a specific privacy law. Returns lawful grounds for processing personal data (e.g. consent, legitimate interest, contractual necessity) with legal_reference (statutory citation) for each basis.",
  inputSchema: {
    law_id: z.string().describe("The law ID (e.g. gdpr-eu, ccpa-ca-us)"),
  },
}, async ({ law_id }) => {
  const result = await request("GET", `/privacy-laws/${encodeURIComponent(law_id)}/legal-bases`);
  return { content: [{ type: "text", text: json(result) }] };
});

server.registerTool("get_penalties", {
  description:
    "Get penalty and enforcement information for a specific privacy law. Returns fine amounts, enforcement authority details, and penalty tiers, each with a legal_reference (statutory citation).",
  inputSchema: {
    law_id: z.string().describe("The law ID (e.g. gdpr-eu, ccpa-ca-us)"),
  },
}, async ({ law_id }) => {
  const result = await request("GET", `/privacy-laws/${encodeURIComponent(law_id)}/penalties`);
  return { content: [{ type: "text", text: json(result) }] };
});

server.registerTool("get_principles", {
  description:
    "Get key principles for a specific privacy law. Returns the foundational principles (e.g. purpose limitation, data minimisation, accountability) each with a legal_reference (statutory citation).",
  inputSchema: {
    law_id: z.string().describe("The law ID (e.g. gdpr-eu, ccpa-ca-us)"),
  },
}, async ({ law_id }) => {
  const result = await request("GET", `/privacy-laws/${encodeURIComponent(law_id)}/principles`);
  return { content: [{ type: "text", text: json(result) }] };
});

server.registerTool("get_exemptions", {
  description:
    "Get exemptions for a specific privacy law. Returns the list of exemptions (e.g. personal/household use, journalism, national security) each with a legal_reference (statutory citation).",
  inputSchema: {
    law_id: z.string().describe("The law ID (e.g. gdpr-eu, ccpa-ca-us)"),
  },
}, async ({ law_id }) => {
  const result = await request("GET", `/privacy-laws/${encodeURIComponent(law_id)}/exemptions`);
  return { content: [{ type: "text", text: json(result) }] };
});

server.registerTool("compare_privacy_laws", {
  description:
    "Compare compliance requirements across multiple privacy laws. Provide at least 2 law IDs. Returns a side-by-side comparison of key requirements, rights, and penalties.",
  inputSchema: {
    law_ids: z.array(z.string()).min(2).describe("List of law IDs to compare (at least 2)"),
  },
}, async ({ law_ids }) => {
  const result = await request("POST", "/privacy-laws/compare", { body: law_ids });
  return { content: [{ type: "text", text: json(result) }] };
});

server.registerTool("search_law_content", {
  description:
    "Keyword search across all privacy law content. Searches descriptions, rights, penalties, notification requirements, etc. Optionally restrict to specific fields.",
  inputSchema: {
    query: z.string().describe("Search query"),
    fields: z.array(z.string()).optional().describe("Restrict search to specific fields (e.g. ['penalties', 'notification_requirements'])"),
  },
}, async ({ query, fields }) => {
  const params = { q: query };
  if (fields && fields.length) params.fields = fields.join(",");
  const result = await request("GET", "/privacy-laws/search", { params });
  return { content: [{ type: "text", text: json(result) }] };
});

server.registerTool("get_applicable_laws", {
  description:
    "Get all privacy laws applicable to the given jurisdictions. Provide a list of jurisdiction names (e.g. ['India', 'European Union', 'California']). Returns all laws that apply to those regions.",
  inputSchema: {
    jurisdictions: z.array(z.string()).describe("List of jurisdiction names"),
  },
}, async ({ jurisdictions }) => {
  const result = await request("POST", "/privacy-laws/applicable", {
    body: { jurisdictions },
  });
  return { content: [{ type: "text", text: json(result) }] };
});

// ── Start ────────────────────────────────────────────────────

const transport = new StdioServerTransport();
await server.connect(transport);
