/**
 * Agent Runtime Layer — Artifact Registry
 *
 * PR-35 Part E：Artifact 注册与追踪系统。
 *
 * 支持：
 *   - Document / Code / Architecture / Design / Test / Release / Report / Metric / Other
 *   - 版本追踪
 *   - 血缘关系（parent artifact）
 *   - Checksum 完整性
 *   - 按 taskId / kind / stepId 检索
 *
 * 纯内存实现，无外部依赖。可替换为持久化实现。
 *
 * @module agent-runtime/artifact-registry
 */

import { ARTIFACT_KIND } from "./domain.mjs";

/**
 * Artifact Registry
 *
 * Usage:
 *   const registry = createArtifactRegistry();
 *   registry.store(artifact);
 *   registry.findByTask("T-001");
 *   registry.findByKind("report");
 */
export function createArtifactRegistry() {
  /** @type {Map<string, object>} */
  const _artifacts = new Map();

  /** @type {Map<string, string[]>} taskId → artifactIds */
  const _byTask = new Map();

  /** @type {Map<string, string[]>} kind → artifactIds */
  const _byKind = new Map();

  const self = { store, get, findByTask, findByKind, findByStep, list, count, getAll, clear };

  // ── store ─────────────────────────────────────────

  /**
   * @param {object} artifact
   * @returns {{ id: string, stored: boolean }}
   */
  function store(artifact) {
    if (!artifact || !artifact.id) {
      return { id: null, stored: false, error: "Invalid artifact: missing id" };
    }

    // 计算 checksum（简单 hash）
    const content = artifact.content || JSON.stringify(artifact.metadata || {});
    artifact.checksum = _simpleHash(content);

    // 如已存在则更新版本
    if (_artifacts.has(artifact.id)) {
      const existing = _artifacts.get(artifact.id);
      artifact.version = (existing.version || 1) + 1;
      artifact.parentArtifactId = existing.id;
    }

    _artifacts.set(artifact.id, { ...artifact });

    // 索引
    if (artifact.taskId) {
      if (!_byTask.has(artifact.taskId)) _byTask.set(artifact.taskId, []);
      const list = _byTask.get(artifact.taskId);
      if (!list.includes(artifact.id)) list.push(artifact.id);
    }

    if (artifact.kind) {
      if (!_byKind.has(artifact.kind)) _byKind.set(artifact.kind, []);
      const list = _byKind.get(artifact.kind);
      if (!list.includes(artifact.id)) list.push(artifact.id);
    }

    return { id: artifact.id, stored: true, version: artifact.version };
  }

  // ── get ───────────────────────────────────────────

  /** @param {string} id */
  function get(id) {
    return _artifacts.get(id) || null;
  }

  // ── findByTask ────────────────────────────────────

  /** @param {string} taskId */
  function findByTask(taskId) {
    const ids = _byTask.get(taskId) || [];
    return ids.map(id => _artifacts.get(id)).filter(Boolean);
  }

  // ── findByKind ────────────────────────────────────

  /** @param {string} kind */
  function findByKind(kind) {
    const ids = _byKind.get(kind) || [];
    return ids.map(id => _artifacts.get(id)).filter(Boolean);
  }

  // ── findByStep ────────────────────────────────────

  /** @param {string} stepId */
  function findByStep(stepId) {
    const result = [];
    for (const a of _artifacts.values()) {
      if (a.stepId === stepId) result.push(a);
    }
    return result;
  }

  // ── list / count / getAll ─────────────────────────

  function list({ kind, taskId } = {}) {
    let result = [..._artifacts.values()];
    if (kind) result = result.filter(a => a.kind === kind);
    if (taskId) result = result.filter(a => a.taskId === taskId);
    return result;
  }

  function count({ kind, taskId } = {}) {
    return self.list({ kind, taskId }).length;
  }

  function getAll() {
    return [..._artifacts.values()];
  }

  // ── clear ─────────────────────────────────────────

  function clear() {
    _artifacts.clear();
    _byTask.clear();
    _byKind.clear();
  }

  return self;
}

// ─── 简单 hash ──────────────────────────────────────

function _simpleHash(str) {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    const char = str.charCodeAt(i);
    hash = ((hash << 5) - hash) + char;
    hash |= 0; // Convert to 32bit integer
  }
  return hash.toString(16);
}
