/**
 * Software Factory Core — Factory Registry
 *
 * PR-36 Part A：注册中心，管理全部 SF-01 ~ SF-15 Factory 的元数据。
 *
 * 每个 Factory 在 Registry 中注册其：
 *   - 基本信息（ID / 名称 / 领域 / 描述）
 *   - 输入类型（接受哪些 artifact kinds）
 *   - 输出类型（产出哪些 artifact kinds）
 *   - 依赖关系（依赖哪些其他 Factory）
 *   - 状态（registered / active / deprecated）
 *
 * Registry 本身不包含 Factory 实现逻辑。
 * SF-01 ~ SF-15 的实现通过外部注入（遵循 Factory Contract）。
 *
 * 设计原则：
 *   - 禁止硬编码 Factory 实现
 *   - Registry 只管理元数据
 *   - 支持按领域/依赖/状态查询
 *   - 与 Workflow Engine 协作
 *
 * @module software-factory-core/factory-registry
 * @since PR-36
 */

import {
  FACTORY_ARTIFACT_KIND, DEPENDENCY_KIND, createFactoryDependency,
} from "./factory-contract.mjs";

// ═══════════════════════════════════════════════════════
// Factory Status
// ═══════════════════════════════════════════════════════

export const FACTORY_STATUS = Object.freeze({
  REGISTERED: "registered",   // 已注册，待激活
  ACTIVE:     "active",       // 已激活，可调用
  DEPRECATED: "deprecated",   // 已废弃
  DISABLED:   "disabled",     // 已禁用
});

// ═══════════════════════════════════════════════════════
// SF-01 ~ SF-15 元数据定义
// ═══════════════════════════════════════════════════════

const { REQUIREMENT, PROTOTYPE, DESIGN, ARCHITECTURE, CODE, TEST, RELEASE, REPORT, OPERATIONS, MARKETING, OTHER } = FACTORY_ARTIFACT_KIND;

/**
 * SF-01 ~ SF-15 Factory 定义表。
 *
 * 每个 Factory 定义包含：
 *   - id: Factory 唯一标识
 *   - name: 中文名称
 *   - domain: 所属领域
 *   - description: 功能描述
 *   - inputKinds: 接受的 artifact 类型
 *   - outputKinds: 产出的 artifact 类型
 *   - dependencies: 依赖的其他 Factory (id + kind)
 *   - status: 当前状态
 */
const FACTORY_DEFINITIONS = Object.freeze([
  // ─── SF-01：Product Strategy ─────────────────────
  {
    id: "SF-01",
    name: "产品战略工厂",
    domain: "product-strategy",
    description: "市场分析、竞品研究、产品定位、战略路线图。输出产品战略文档。",
    inputKinds: [OTHER],
    outputKinds: [REQUIREMENT, REPORT],
    dependencies: [],
  },

  // ─── SF-02：Requirement Engineering ──────────────
  {
    id: "SF-02",
    name: "需求工程工厂",
    domain: "requirement-engineering",
    description: "PRD 生成、需求拆解、用例建模、验收标准定义。",
    inputKinds: [REQUIREMENT],
    outputKinds: [REQUIREMENT, PROTOTYPE],
    dependencies: [
      { from: "SF-01", kind: DEPENDENCY_KIND.DATA, description: "接收产品战略作为需求输入" },
    ],
  },

  // ─── SF-04：Visual Design ────────────────────────
  {
    id: "SF-04",
    name: "视觉设计工厂",
    domain: "visual-design",
    description: "设计系统、组件库、视觉稿、品牌规范。",
    inputKinds: [DESIGN, PROTOTYPE],
    outputKinds: [DESIGN],
    dependencies: [

    ],
  },

  // ─── SF-05：Architecture ─────────────────────────
  {
    id: "SF-05",
    name: "技术架构工厂",
    domain: "architecture",
    description: "架构决策记录(ADR)、技术选型、系统设计、API 设计。",
    inputKinds: [REQUIREMENT, DESIGN],
    outputKinds: [ARCHITECTURE, CODE],
    dependencies: [
      { from: "SF-02", kind: DEPENDENCY_KIND.DATA, description: "接收需求作为架构决策依据" },

    ],
  },

  // ─── SF-06：Platform Planning ────────────────────
  {
    id: "SF-06",
    name: "平台规划工厂",
    domain: "platform-planning",
    description: "基础设施规划、部署架构、容量规划、成本估算。",
    inputKinds: [ARCHITECTURE],
    outputKinds: [ARCHITECTURE, REPORT],
    dependencies: [
      { from: "SF-05", kind: DEPENDENCY_KIND.DATA, description: "接收架构设计作为平台规划输入" },
    ],
  },

  // ─── SF-07：Full Stack Development ───────────────
  {
    id: "SF-07",
    name: "全栈开发工厂",
    domain: "full-stack-development",
    description: "前端/后端/数据库/API 全栈开发。代码生成、集成、构建。",
    inputKinds: [ARCHITECTURE, DESIGN, REQUIREMENT],
    outputKinds: [CODE, TEST],
    dependencies: [
      { from: "SF-05", kind: DEPENDENCY_KIND.HARD, description: "必须基于架构设计进行开发" },
      { from: "SF-04", kind: DEPENDENCY_KIND.SOFT, description: "参考视觉设计进行前端开发" },
      { from: "SF-06", kind: DEPENDENCY_KIND.SOFT, description: "参考平台规划进行部署适配" },
    ],
  },

  // ─── SF-08：Agent Factory ────────────────────────
  {
    id: "SF-08",
    name: "Agent 协作工厂",
    domain: "agent-collaboration",
    description: "多 Agent 编排、通信协议、任务分配、Agent 间协作。",
    inputKinds: [REQUIREMENT, CODE],
    outputKinds: [CODE, REPORT],
    dependencies: [
      { from: "SF-02", kind: DEPENDENCY_KIND.SOFT, description: "根据需求定义 Agent 角色" },
    ],
  },

  // ─── SF-09：Quality ──────────────────────────────
  {
    id: "SF-09",
    name: "质量治理工厂",
    domain: "quality-governance",
    description: "代码审查、质量门禁、合规检查、技术债务管理。",
    inputKinds: [CODE, TEST, ARCHITECTURE],
    outputKinds: [REPORT, OTHER],
    dependencies: [
      { from: "SF-07", kind: DEPENDENCY_KIND.HARD, description: "对开发产出进行质量治理" },
    ],
  },

  // ─── SF-10：Testing ──────────────────────────────
  {
    id: "SF-10",
    name: "测试工厂",
    domain: "testing",
    description: "单元测试、集成测试、E2E 测试、性能测试、安全测试。",
    inputKinds: [CODE, ARCHITECTURE],
    outputKinds: [TEST, REPORT],
    dependencies: [
      { from: "SF-07", kind: DEPENDENCY_KIND.HARD, description: "对开发代码执行测试" },
      { from: "SF-09", kind: DEPENDENCY_KIND.SOFT, description: "根据质量标准制定测试策略" },
    ],
  },

  // ─── SF-11：Release ──────────────────────────────
  {
    id: "SF-11",
    name: "发布工厂",
    domain: "release",
    description: "版本管理、发布流水线、制品管理、部署编排。",
    inputKinds: [CODE, TEST, REPORT],
    outputKinds: [RELEASE, REPORT],
    dependencies: [
      { from: "SF-09", kind: DEPENDENCY_KIND.HARD, description: "质量通过后方可发布" },
      { from: "SF-10", kind: DEPENDENCY_KIND.HARD, description: "测试通过后方可发布" },
    ],
  },

  // ─── SF-12：Operations ───────────────────────────
  {
    id: "SF-12",
    name: "运维工厂",
    domain: "operations",
    description: "监控告警、日志管理、故障处理、性能优化、容量管理。",
    inputKinds: [RELEASE, REPORT],
    outputKinds: [OPERATIONS, REPORT],
    dependencies: [
      { from: "SF-11", kind: DEPENDENCY_KIND.TRIGGER, description: "发布完成后启动运维监控" },
    ],
  },

  // ─── SF-13：Evolution ────────────────────────────
  {
    id: "SF-13",
    name: "演进工厂",
    domain: "evolution",
    description: "产品迭代规划、技术演进、架构升级、债务偿还。",
    inputKinds: [OPERATIONS, REPORT],
    outputKinds: [REQUIREMENT, REPORT],
    dependencies: [
      { from: "SF-12", kind: DEPENDENCY_KIND.DATA, description: "根据运维数据驱动产品演进" },
      { from: "SF-01", kind: DEPENDENCY_KIND.SOFT, description: "演进方向对齐产品战略" },
    ],
  },

  // ─── SF-14：Growth ───────────────────────────────
  {
    id: "SF-14",
    name: "增长工厂",
    domain: "growth",
    description: "数据分析、A/B 测试、用户增长、转化优化、营销自动化。",
    inputKinds: [OPERATIONS, REPORT],
    outputKinds: [REPORT, MARKETING],
    dependencies: [
      { from: "SF-12", kind: DEPENDENCY_KIND.DATA, description: "基于运维数据进行增长分析" },
    ],
  },

  // ─── SF-15：Software Company ─────────────────────
  {
    id: "SF-15",
    name: "软件公司工厂",
    domain: "software-company",
    description: "项目管理、资源分配、团队协作、财务规划、公司运营。",
    inputKinds: [REPORT],
    outputKinds: [REPORT],
    dependencies: [
      { from: "SF-01", kind: DEPENDENCY_KIND.SOFT, description: "战略对齐" },
      { from: "SF-13", kind: DEPENDENCY_KIND.SOFT, description: "演进反馈" },
      { from: "SF-14", kind: DEPENDENCY_KIND.SOFT, description: "增长数据" },
    ],
  },
]);

// ═══════════════════════════════════════════════════════
// FactoryRegistry
// ═══════════════════════════════════════════════════════

/**
 * 创建 Factory Registry 实例。
 *
 * Registry 管理所有 SF-01 ~ SF-15 的元数据。
 * 实际的 Factory 执行器通过 registerImplementation() 注入。
 *
 * Usage:
 *   const registry = createFactoryRegistry();
 *   registry.get("SF-07"); // → Factory 元数据
 *   registry.getDependencies("SF-07"); // → 依赖工厂列表
 *   registry.registerImplementation("SF-07", myFullStackFactory);
 *
 * @returns {object} FactoryRegistry
 */
export function createFactoryRegistry() {
  /** @type {Map<string, object>} id → factory metadata */
  const _factories = new Map();

  /** @type {Map<string, function>} id → factory implementation */
  const _implementations = new Map();

  /** @type {Map<string, object[]>} id → dependency objects */
  const _depsByTarget = new Map();

  /** @type {Map<string, string[]>} id → dependents (反向依赖) */
  const _dependents = new Map();

  // ── Initialize with SF-01 ~ SF-15 ──────────────

  for (const def of FACTORY_DEFINITIONS) {
    _registerDefinition(def);
  }

  // ── Private ────────────────────────────────────

  function _registerDefinition(def) {
    const entry = {
      ...def,
      status: FACTORY_STATUS.REGISTERED,
      registeredAt: new Date().toISOString(),
      activatedAt: null,
      implementationId: null,
    };

    _factories.set(def.id, entry);
  }

  // ── Public API ─────────────────────────────────

  /**
   * 获取 Factory 元数据。
   * @param {string} id — Factory ID (SF-01 ~ SF-15)
   * @returns {object|null}
   */
  function get(id) {
    return _factories.get(id) || null;
  }

  /**
   * 列出所有 Factory。
   * @param {object} [opts]
   * @param {string} [opts.domain]  — 按领域过滤
   * @param {string} [opts.status]  — 按状态过滤
   * @returns {object[]}
   */
  function list({ domain, status } = {}) {
    let result = [..._factories.values()];
    if (domain) result = result.filter(f => f.domain === domain);
    if (status) result = result.filter(f => f.status === status);
    return result;
  }

  /**
   * 获取 Factory 的上游依赖列表。
   * @param {string} id
   * @returns {object[]} FactoryDependency 对象列表
   */
  function getDependencies(id) {
    const factory = _factories.get(id);
    if (!factory) return [];

    return (factory.dependencies || []).map(d => createFactoryDependency({
      from: d.from,
      to: id,
      kind: d.kind,
      required: d.required !== false,
      description: d.description || "",
    }));
  }

  /**
   * 获取依赖此 Factory 的下游 Factory 列表（反向依赖）。
   * @param {string} id
   * @returns {object[]}
   */
  function getDependents(id) {
    if (_dependents.has(id)) {
      return _dependents.get(id).map(depId => _factories.get(depId)).filter(Boolean);
    }
    // compute lazily
    const deps = [];
    for (const [fid, f] of _factories) {
      if ((f.dependencies || []).some(d => d.from === id)) {
        deps.push(fid);
      }
    }
    _dependents.set(id, deps);
    return deps.map(depId => _factories.get(depId)).filter(Boolean);
  }

  /**
   * 获取完整的 Factory 拓扑排序（依赖顺序）。
   * 用于 Workflow Engine 按正确顺序执行。
   * @returns {string[]} Factory ID 列表
   */
  function getTopologicalOrder() {
    const visited = new Set();
    const visiting = new Set();
    const result = [];

    function visit(fid) {
      if (visited.has(fid)) return;
      if (visiting.has(fid)) {
        // 循环依赖检测 — 跳过
        return;
      }
      visiting.add(fid);

      const factory = _factories.get(fid);
      if (factory?.dependencies) {
        for (const d of factory.dependencies) {
          visit(d.from);
        }
      }

      visiting.delete(fid);
      visited.add(fid);
      result.push(fid);
    }

    for (const fid of _factories.keys()) {
      visit(fid);
    }

    return result;
  }

  /**
   * 获取可并行执行的 Factory 批次。
   *
   * 批量执行策略：
   *   Batch 1: SF-01 (无依赖)
   *   Batch 2: SF-02 (依赖 SF-01)
   *   Batch 3: SF-05, SF-08 (依赖 SF-02)
   *   Batch 4: SF-04 (依赖 SF-02), SF-06 (依赖 SF-05)
   *   Batch 5: SF-07 (依赖 SF-04/05/06)
   *   Batch 6: SF-09, SF-10 (依赖 SF-07)
   *   Batch 7: SF-11 (依赖 SF-09/10)
   *   Batch 8: SF-12 (依赖 SF-11)
   *   Batch 9: SF-13, SF-14 (依赖 SF-12)
   *   Batch 10: SF-15 (依赖 SF-01/13/14)
   *
   * @returns {string[][]} 每批次的 Factory ID 列表
   */
  function getParallelBatches() {
    const order = getTopologicalOrder();
    const batches = [];
    const completed = new Set();

    while (completed.size < order.length) {
      const batch = [];
      for (const fid of order) {
        if (completed.has(fid)) continue;
        const factory = _factories.get(fid);
        if (!factory) continue;

        const depsMet = (factory.dependencies || []).every(d => completed.has(d.from));
        if (depsMet) {
          batch.push(fid);
        }
      }

      if (batch.length === 0) {
        // 循环依赖或死锁，把剩余的加入最后一批
        for (const fid of order) {
          if (!completed.has(fid)) batch.push(fid);
        }
        if (batch.length > 0) batches.push(batch);
        break;
      }

      batches.push(batch);
      for (const fid of batch) completed.add(fid);
    }

    return batches;
  }

  // ── Implementation Management ──────────────────

  /**
   * 注册 Factory 实现。
   *
   * Factory 实现必须遵循 Factory Contract：
   *   入参：FactoryInput
   *   出参：FactoryOutput
   *
   * @param {string} id          — Factory ID
   * @param {function} implFn    — (FactoryInput) => FactoryOutput
   * @throws {Error} 如果 Factory ID 不存在
   */
  function registerImplementation(id, implFn) {
    if (!_factories.has(id)) {
      throw new Error(`Unknown factory: ${id}. Register the factory definition first.`);
    }
    if (typeof implFn !== "function") {
      throw new TypeError(`Implementation for ${id} must be a function.`);
    }

    const factory = _factories.get(id);
    factory.implementationId = `impl-${id}-${Date.now()}`;
    factory.status = FACTORY_STATUS.ACTIVE;
    if (!factory.activatedAt) factory.activatedAt = new Date().toISOString();

    _implementations.set(id, implFn);
  }

  /**
   * 获取 Factory 实现。
   * @param {string} id
   * @returns {function|null}
   */
  function getImplementation(id) {
    return _implementations.get(id) || null;
  }

  /**
   * 执行 Factory（需要先注册实现）。
   * @param {string} id       — Factory ID
   * @param {object} input    — FactoryInput
   * @returns {object} FactoryOutput
   * @throws {Error} 如果未注册实现
   */
  function execute(id, input) {
    const impl = _implementations.get(id);
    if (!impl) {
      throw new Error(`No implementation registered for ${id}. Call registerImplementation() first.`);
    }
    return impl(input);
  }

  /**
   * 设置 Factory 状态。
   * @param {string} id
   * @param {"registered"|"active"|"deprecated"|"disabled"} status
   */
  function setStatus(id, status) {
    if (!_factories.has(id)) throw new Error(`Unknown factory: ${id}`);
    if (!FACTORY_STATUS[status.toUpperCase()]) throw new TypeError(`Invalid status: ${status}`);
    _factories.get(id).status = status;
  }

  /**
   * 获取 Registry 统计信息。
   * @returns {object}
   */
  function stats() {
    const all = [..._factories.values()];
    const byStatus = {};
    for (const f of all) {
      byStatus[f.status] = (byStatus[f.status] || 0) + 1;
    }
    return {
      total: all.length,
      byStatus,
      implemented: _implementations.size,
      domains: [...new Set(all.map(f => f.domain))],
    };
  }

  /**
   * 清空 Registry（仅清空实现，保留定义）。
   */
  function clearImplementations() {
    _implementations.clear();
    for (const f of _factories.values()) {
      f.status = FACTORY_STATUS.REGISTERED;
      f.implementationId = null;
      f.activatedAt = null;
    }
  }

  return {
    get,
    list,
    getDependencies,
    getDependents,
    getTopologicalOrder,
    getParallelBatches,
    registerImplementation,
    getImplementation,
    execute,
    setStatus,
    stats,
    clearImplementations,
  };
}
