import { buildLinkAnnotations } from "./link-annotations.mjs";
import { buildWorkspacePolicyContext } from "./workspace-policy.mjs";

const ROUTEC_PROVIDER_MARKDOWN_LINK_ANNOTATION_SEMANTIC_TYPES = new Set([
  "message.assistant",
  "thinking.reasoning",
]);
const ROUTEC_LINK_ANNOTATION_BODY_MAX_CHARS = 20000;

function isObject(value) {
  return value !== null && typeof value === "object" && !Array.isArray(value);
}

export function shouldAnnotateRouteCProviderSemanticMarkdownLinks({
  semanticType,
  body,
}) {
  return (
    ROUTEC_PROVIDER_MARKDOWN_LINK_ANNOTATION_SEMANTIC_TYPES.has(
      semanticType
    ) &&
    typeof body === "string" &&
    body.trim().length > 0 &&
    body.length <= ROUTEC_LINK_ANNOTATION_BODY_MAX_CHARS
  );
}

export function buildRouteCMatrixContentAssetLinkAnnotations({
  content,
  agentId = "",
  agentRoot = "",
  workspacePolicy = null,
  assetReadablePaths = [],
}) {
  if (content?.msgtype !== "m.text" || typeof content.body !== "string") {
    return [];
  }
  if (content.body.length > ROUTEC_LINK_ANNOTATION_BODY_MAX_CHARS) {
    return [];
  }
  if (!agentRoot) return [];
  const workspaceContext = buildWorkspacePolicyContext({
    workspacePolicy,
    assetReadablePaths,
  });
  return buildLinkAnnotations({
    text: content.body,
    agentId,
    agentRoot,
    includeAppFilePreviewMarkdown: true,
    allowedRoots: workspaceContext.readablePaths,
  }).filter(
    (annotation) =>
      annotation.kind === "file_preview_link" ||
      annotation.kind === "directory_link"
  );
}

export function attachRouteCMatrixContentAssetLinkAnnotations({
  content,
  agentId = "",
  agentRoot = "",
  workspacePolicy = null,
  assetReadablePaths = [],
}) {
  if (!isObject(content)) return content;
  if (
    Array.isArray(content.link_annotations) &&
    content.link_annotations.length > 0
  ) {
    return content;
  }
  const annotations = buildRouteCMatrixContentAssetLinkAnnotations({
    content,
    agentId,
    agentRoot,
    workspacePolicy,
    assetReadablePaths,
  });
  if (annotations.length === 0) return content;
  return {
    ...content,
    link_annotations: annotations,
  };
}

export function attachRouteCProviderSemanticMarkdownLinkAnnotationsForContent({
  content,
  semanticType,
  body,
  agentId = "",
  agentRoot = "",
  workspacePolicy = null,
  assetReadablePaths = [],
}) {
  if (
    !shouldAnnotateRouteCProviderSemanticMarkdownLinks({
      semanticType,
      body,
    })
  ) {
    return content;
  }
  return attachRouteCMatrixContentAssetLinkAnnotations({
    content,
    agentId,
    agentRoot,
    workspacePolicy,
    assetReadablePaths,
  });
}
