import { describe, expect, test } from "bun:test";
import {
  githubTokenEnvNameForSecretKey,
  readGiteaConfig,
  resolveTarget,
} from "./platform-infra-gitea-config";
import { buildGiteaMirrorBootstrapCredentialPreflight, buildMirrorWebhookCredentialBlockedResult, renderManifest } from "./platform-infra-gitea";
import { renderMirrorWebhookCredentialBlocked } from "./platform-infra-gitea-render";

function syntheticMissingSelfmediaCredential(): Record<string, unknown> {
  return {
    id: "github-upstream:selfmedia-nc01",
    repository: "pikainc/selfmedia",
    sourceRef: "pikainc-selfmedia-gh-token.txt",
    present: false,
    requiredKeysPresent: false,
    fingerprint: null,
    permissionResult: {
      status: "blocked-missing-credential",
      permissions: { contents: "read", metadata: "read", webhooks: "read-write" },
      error: "credential material is absent",
    },
    valuesPrinted: false,
  };
}

function syntheticBlockedResult(allTargetRepositories = false): Record<string, unknown> {
  const config = readGiteaConfig();
  const target = resolveTarget(config, "NC01");
  const repositories = config.sourceAuthority.repositories.filter((repo) => repo.targetId === "NC01"
    && (allTargetRepositories || repo.key === "selfmedia-nc01"));
  const credential = syntheticMissingSelfmediaCredential();
  return buildMirrorWebhookCredentialBlockedResult(config, target, repositories, [credential], [String(credential.id)]);
}

describe("platform-infra Gitea repository GitHub credentials", () => {
  test("keeps the global credential and selfmedia override on distinct Secret keys", () => {
    const config = readGiteaConfig();
    const globalCredential = config.sourceAuthority.credentials.github;
    const selfmedia = config.sourceAuthority.repositories.find((repo) => repo.key === "selfmedia-nc01");
    const override = selfmedia?.credentialOverride?.github;

    expect(override?.sourceRef).toBe("pikainc-selfmedia-gh-token.txt");
    expect(override?.permissions).toEqual({ contents: "read", metadata: "read", webhooks: "read-write" });
    expect(override?.gitFetchCredential.secretRef.key).not.toBe(globalCredential.gitFetchCredential.secretRef.key);
    expect(githubTokenEnvNameForSecretKey(override?.gitFetchCredential.secretRef.key ?? ""))
      .not.toBe(githubTokenEnvNameForSecretKey(globalCredential.gitFetchCredential.secretRef.key));
  });

  test("keeps PikaOA master and release authorities on distinct Secret keys", () => {
    const config = readGiteaConfig();
    const developmentAuthority = config.sourceAuthority.repositories.find((repo) => repo.key === "pikaoa-dev-nc01");
    const productionAuthority = config.sourceAuthority.repositories.find((repo) => repo.key === "pikaoa-nc01");
    const developmentKey = developmentAuthority?.credentialOverride?.github.gitFetchCredential.secretRef.key;
    const productionKey = productionAuthority?.credentialOverride?.github.gitFetchCredential.secretRef.key;

    expect(developmentAuthority?.upstream.branch).toBe("master");
    expect(productionAuthority?.upstream.branch).toBe("release");
    expect(developmentKey).toBe("github-token-pikainc-pikaoa");
    expect(productionKey).toBe("github-token-pikainc-pikaoa-release");
    expect(productionKey).not.toBe(developmentKey);
    expect(githubTokenEnvNameForSecretKey(productionKey ?? ""))
      .not.toBe(githubTokenEnvNameForSecretKey(developmentKey ?? ""));
  });

  test("normalizes Secret keys to bounded environment variable names", () => {
    expect(githubTokenEnvNameForSecretKey("github-token-pikainc-selfmedia"))
      .toBe("UNIDESK_GITEA_GITHUB_TOKEN_GITHUB_TOKEN_PIKAINC_SELFMEDIA");
  });

  test("keeps repository credential overrides scoped to their configured target", () => {
    const config = readGiteaConfig();
    const jd01Overrides = config.sourceAuthority.repositories
      .filter((repo) => repo.targetId === "JD01")
      .flatMap((repo) => repo.credentialOverride?.github ?? []);
    const nc01Overrides = config.sourceAuthority.repositories
      .filter((repo) => repo.targetId === "NC01")
      .flatMap((repo) => repo.credentialOverride?.github ?? []);

    expect(jd01Overrides).toHaveLength(0);
    expect(nc01Overrides.map((credential) => credential.sourceRef)).toContain("pikainc-selfmedia-gh-token.txt");
  });

  test("bootstrap preflight only requires the selected repository effective credential", () => {
    const config = readGiteaConfig();
    const repository = config.sourceAuthority.repositories.find((repo) => repo.key === "selfmedia-nc01");
    expect(repository).toBeDefined();
    const result = buildGiteaMirrorBootstrapCredentialPreflight(config, [repository!], (credential) => (
      credential.sourceRef === "pikainc-selfmedia-gh-token.txt"
        ? { [credential.sourceKey]: "fixture-token" }
        : null
    ));

    expect(result.blockers).toEqual([]);
    expect(result.credentials).toHaveLength(1);
    expect(result.credentials[0]).toMatchObject({
      id: "github-upstream:selfmedia-nc01",
      sourceRef: "pikainc-selfmedia-gh-token.txt",
      present: true,
      requiredKeysPresent: true,
    });
    expect(JSON.stringify(result)).not.toContain(config.sourceAuthority.credentials.admin.sourceRef);
    expect(JSON.stringify(result)).not.toContain(config.sourceAuthority.credentials.github.sourceRef);
  });

  test("production PikaOA status scope never reads the unselected master credential", () => {
    const config = readGiteaConfig();
    const production = config.sourceAuthority.repositories.find((repo) => repo.key === "pikaoa-nc01");
    expect(production).toBeDefined();
    const requested: string[] = [];
    const result = buildGiteaMirrorBootstrapCredentialPreflight(config, [production!], (credential) => {
      requested.push(credential.gitFetchCredential.secretRef.key);
      return { [credential.sourceKey]: "fixture-release-token" };
    });

    expect(result.blockers).toEqual([]);
    expect(requested).toEqual(["github-token-pikainc-pikaoa-release"]);
    expect(result.credentials).toHaveLength(1);
    expect(result.credentials[0]).toMatchObject({
      id: "github-upstream:pikaoa-nc01",
      valuesPrinted: false,
    });
  });

  test("does not inject the NC01 selfmedia token into JD01 bridge containers", () => {
    const config = readGiteaConfig();
    const selfmediaTokenEnv = githubTokenEnvNameForSecretKey("github-token-pikainc-selfmedia");
    const globalTokenEnv = githubTokenEnvNameForSecretKey(config.sourceAuthority.credentials.github.gitFetchCredential.secretRef.key);
    const jd01Manifest = renderManifest(config, resolveTarget(config, "JD01"));
    const nc01Manifest = renderManifest(config, resolveTarget(config, "NC01"));

    expect(jd01Manifest).toContain(globalTokenEnv);
    expect(jd01Manifest).not.toContain(selfmediaTokenEnv);
    expect(nc01Manifest).toContain(globalTokenEnv);
    expect(nc01Manifest).toContain(selfmediaTokenEnv);
    expect(nc01Manifest).toContain(`"tokenEnv": "${selfmediaTokenEnv}"`);
  });

  test("runs the GitHub sync bridge and candidate under the YAML-declared init reaper", () => {
    const config = readGiteaConfig();
    const target = resolveTarget(config, "NC01");
    const manifest = renderManifest(config, target);

    expect(config.sourceAuthority.webhookSync.bridge.initCommand).toEqual(["/usr/bin/tini", "--"]);
    expect(manifest).toContain('command:\n            - "/usr/bin/tini"\n            - "--"\n            - node\n            - /etc/gitea-github-sync/entrypoint.mjs');
    expect(manifest).toContain('command:\n            - "/usr/bin/tini"\n            - "--"\n            - /bin/sh\n            - -eu');
  });

  test("keeps missing selfmedia webhook status bounded and stack-free", () => {
    const payload = syntheticBlockedResult();
    const credentials = payload.credentials as Array<Record<string, unknown>>;
    const selfmedia = credentials[0];
    const serialized = JSON.stringify(payload);

    expect((payload.error as Record<string, unknown>).code).toBe("github-credential-unavailable");
    expect(selfmedia).toMatchObject({
      sourceRef: "pikainc-selfmedia-gh-token.txt",
      present: false,
      fingerprint: null,
      valuesPrinted: false,
    });
    expect(selfmedia).not.toHaveProperty("sourcePath");
    expect(serialized).not.toContain('"stack"');
    expect(serialized).not.toContain("/root/.worktrees/");
  });

  test("renders missing selfmedia webhook status as compact text by default", () => {
    const stdout = renderMirrorWebhookCredentialBlocked(syntheticBlockedResult()).renderedText;

    expect(stdout).toContain("PLATFORM-INFRA GITEA MIRROR WEBHOOK STATUS");
    expect(stdout).toContain("SOURCE_REF");
    expect(stdout).toContain("pikainc-selfmedia-gh-token.txt");
    expect(stdout).toContain("PERMISSION_RESULT");
    expect(stdout).toContain("github-upstream:selfmedia-nc01");
    expect(stdout.trimStart()).not.toStartWith("{");
    expect(stdout).not.toContain('"stack"');
  });

  test("matches compact blocker rows to their repository without --repo", () => {
    const stdout = renderMirrorWebhookCredentialBlocked(syntheticBlockedResult(true)).renderedText;

    expect(stdout).toContain("pikainc/selfmedia");
    expect(stdout).toContain("pikainc-selfmedia-gh-token.txt");
    expect(stdout).toContain("github-upstream:selfmedia-nc01");
    expect(stdout).not.toContain("pikasTech/agentrun");
    expect(stdout.trimStart()).not.toStartWith("{");
  });
});
