import {
  WU_LIFECYCLE_CLAIM_DEFAULTS,
  WU_LIFECYCLE_COMMANDS,
  WU_LIFECYCLE_EVENT_KINDS,
  WU_LIFECYCLE_EVENT_SCHEMA_VERSION,
  WU_LIFECYCLE_SPEC_HASH,
  WU_LIFECYCLE_SYNC_CONFIG,
  WU_LIFECYCLE_SYNC_LOG_PREFIX,
  WU_LIFECYCLE_SYNC_RESULT_DEFAULTS,
  WU_LIFECYCLE_SYNC_SKIPPED_REASONS
} from "./chunk-EK2AKZKD.js";
import {
  CONFIG_FILES
} from "./chunk-DWMLTXKQ.js";
import {
  ErrorCodes,
  createError,
  getErrorMessage
} from "./chunk-RXRKBBSM.js";

// src/wu-lifecycle-sync/service.ts
import { createHash } from "crypto";
import { readFileSync } from "fs";

// src/wu-lifecycle-sync/control-plane-sink.ts
import path from "path";
import { readFile } from "fs/promises";
import YAML from "yaml";

// src/wu-lifecycle-sync/noop-sink.ts
function createNoopSink(skippedReason) {
  return {
    async push() {
      return {
        sent: WU_LIFECYCLE_SYNC_RESULT_DEFAULTS.SENT,
        accepted: WU_LIFECYCLE_SYNC_RESULT_DEFAULTS.ACCEPTED,
        skippedReason
      };
    }
  };
}

// src/wu-lifecycle-sync/control-plane-sink.ts
function isRecord(value) {
  return typeof value === "object" && value !== null;
}
function asNonEmptyString(value) {
  if (typeof value !== "string") {
    return void 0;
  }
  const trimmed = value.trim();
  return trimmed.length > 0 ? trimmed : void 0;
}
function createNoopSyncResult(skippedReason) {
  return {
    sent: WU_LIFECYCLE_SYNC_RESULT_DEFAULTS.SENT,
    accepted: WU_LIFECYCLE_SYNC_RESULT_DEFAULTS.ACCEPTED,
    skippedReason
  };
}
function createParseInput(workspaceId, controlPlaneRaw) {
  return {
    [WU_LIFECYCLE_SYNC_CONFIG.WORKSPACE_ID_FIELD]: workspaceId,
    [WU_LIFECYCLE_SYNC_CONFIG.CONTROL_PLANE_FIELD]: controlPlaneRaw
  };
}
async function loadControlPlaneSdk(logger) {
  try {
    return await import("./dist-IY3UUMWK.js");
  } catch (error) {
    logger?.warn?.(
      `${WU_LIFECYCLE_SYNC_LOG_PREFIX} control-plane SDK unavailable: ${getErrorMessage(error)}`
    );
    return null;
  }
}
async function resolveWuLifecycleEventSink(options = {}) {
  const workspaceRoot = options.workspaceRoot ?? process.cwd();
  const workspacePath = path.join(workspaceRoot, CONFIG_FILES.WORKSPACE_CONFIG);
  let workspaceContent;
  try {
    workspaceContent = await readFile(workspacePath, WU_LIFECYCLE_SYNC_CONFIG.TEXT_ENCODING_UTF8);
  } catch {
    return createNoopSink(WU_LIFECYCLE_SYNC_SKIPPED_REASONS.WORKSPACE_CONFIG_MISSING);
  }
  let parsedWorkspace;
  try {
    parsedWorkspace = YAML.parse(workspaceContent);
  } catch {
    return createNoopSink(WU_LIFECYCLE_SYNC_SKIPPED_REASONS.WORKSPACE_CONFIG_INVALID);
  }
  if (!isRecord(parsedWorkspace)) {
    return createNoopSink(WU_LIFECYCLE_SYNC_SKIPPED_REASONS.WORKSPACE_CONFIG_INVALID);
  }
  const workspaceId = asNonEmptyString(
    Reflect.get(parsedWorkspace, WU_LIFECYCLE_SYNC_CONFIG.WORKSPACE_ID_FIELD)
  );
  if (!workspaceId) {
    return createNoopSink(WU_LIFECYCLE_SYNC_SKIPPED_REASONS.WORKSPACE_ID_MISSING);
  }
  const controlPlaneRaw = Reflect.get(
    parsedWorkspace,
    WU_LIFECYCLE_SYNC_CONFIG.CONTROL_PLANE_FIELD
  );
  if (!isRecord(controlPlaneRaw)) {
    return createNoopSink(WU_LIFECYCLE_SYNC_SKIPPED_REASONS.CONTROL_PLANE_NOT_CONFIGURED);
  }
  const controlPlaneSdk = await loadControlPlaneSdk(options.logger);
  if (!controlPlaneSdk) {
    return createNoopSink(WU_LIFECYCLE_SYNC_SKIPPED_REASONS.CONTROL_PLANE_SDK_UNAVAILABLE);
  }
  const { parseWorkspaceControlPlaneConfig, createHttpControlPlaneSyncPort } = controlPlaneSdk;
  let runtimeConfig;
  try {
    runtimeConfig = parseWorkspaceControlPlaneConfig(
      createParseInput(workspaceId, controlPlaneRaw)
    );
  } catch {
    return createNoopSink(WU_LIFECYCLE_SYNC_SKIPPED_REASONS.CONTROL_PLANE_INVALID);
  }
  const environment = options.environment ?? process.env;
  const tokenEnv = runtimeConfig.control_plane.auth.token_env;
  const token = asNonEmptyString(environment[tokenEnv]);
  if (!token) {
    return createNoopSink(WU_LIFECYCLE_SYNC_SKIPPED_REASONS.MISSING_TOKEN_ENV);
  }
  const syncPort = createHttpControlPlaneSyncPort(runtimeConfig.control_plane, options.logger, {
    fetchFn: options.fetchFn,
    environment,
    timeoutMs: options.timeoutMs
  });
  return {
    async push(events) {
      if (events.length === 0) {
        return createNoopSyncResult(WU_LIFECYCLE_SYNC_SKIPPED_REASONS.NO_EVENTS);
      }
      try {
        const result = await syncPort.pushKernelEvents({
          workspace_id: workspaceId,
          events
        });
        return {
          sent: result.accepted > 0,
          accepted: result.accepted,
          ...result.accepted > 0 ? {} : {
            skippedReason: WU_LIFECYCLE_SYNC_SKIPPED_REASONS.NO_EVENTS_ACCEPTED
          }
        };
      } catch (error) {
        options.logger?.warn?.(
          `${WU_LIFECYCLE_SYNC_LOG_PREFIX} pushKernelEvents failed: ${getErrorMessage(error)}`
        );
        return createNoopSyncResult(WU_LIFECYCLE_SYNC_SKIPPED_REASONS.PUSH_FAILED);
      }
    }
  };
}

// src/wu-lifecycle-sync/service.ts
function asNonEmptyString2(value) {
  if (typeof value !== "string") {
    return void 0;
  }
  const trimmed = value.trim();
  return trimmed.length > 0 ? trimmed : void 0;
}
function createSha256Hex(input) {
  return createHash(WU_LIFECYCLE_SPEC_HASH.ALGORITHM).update(input).digest(WU_LIFECYCLE_SPEC_HASH.DIGEST_ENCODING);
}
function resolveSpecHash(input) {
  const explicitSpecHash = asNonEmptyString2(input.specHash);
  if (explicitSpecHash && WU_LIFECYCLE_SPEC_HASH.HEX_256_REGEX.test(explicitSpecHash)) {
    return explicitSpecHash;
  }
  const specPath = asNonEmptyString2(input.specPath);
  if (specPath) {
    try {
      const fileContent = readFileSync(specPath, WU_LIFECYCLE_SYNC_CONFIG.TEXT_ENCODING_UTF8);
      return createSha256Hex(fileContent);
    } catch {
    }
  }
  return createSha256Hex(`${WU_LIFECYCLE_COMMANDS.CREATE}:${input.wuId}`);
}
function resolveTimestamp(input) {
  return input.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
}
function buildWuLifecycleKernelEvent(input) {
  const timestamp = resolveTimestamp(input);
  switch (input.command) {
    case WU_LIFECYCLE_COMMANDS.CREATE:
      return {
        schema_version: WU_LIFECYCLE_EVENT_SCHEMA_VERSION,
        kind: WU_LIFECYCLE_EVENT_KINDS.CREATE,
        task_id: input.wuId,
        timestamp,
        spec_hash: resolveSpecHash(input)
      };
    case WU_LIFECYCLE_COMMANDS.CLAIM:
      return {
        schema_version: WU_LIFECYCLE_EVENT_SCHEMA_VERSION,
        kind: WU_LIFECYCLE_EVENT_KINDS.CLAIM,
        task_id: input.wuId,
        timestamp,
        by: asNonEmptyString2(input.by) ?? WU_LIFECYCLE_CLAIM_DEFAULTS.ACTOR,
        session_id: asNonEmptyString2(input.sessionId) ?? WU_LIFECYCLE_CLAIM_DEFAULTS.SESSION_ID
      };
    case WU_LIFECYCLE_COMMANDS.DONE:
      return {
        schema_version: WU_LIFECYCLE_EVENT_SCHEMA_VERSION,
        kind: WU_LIFECYCLE_EVENT_KINDS.DONE,
        task_id: input.wuId,
        timestamp,
        ...input.evidenceRefs && input.evidenceRefs.length > 0 ? { evidence_refs: input.evidenceRefs } : {}
      };
    default: {
      const exhaustiveCheck = input.command;
      throw createError(
        ErrorCodes.INVALID_ARGUMENT,
        `Unsupported WU lifecycle command: ${exhaustiveCheck}`
      );
    }
  }
}
async function flushWuLifecycleSync(input, options = {}) {
  const logger = options.logger;
  try {
    const sink = options.sink ?? await resolveWuLifecycleEventSink(options);
    const event = buildWuLifecycleKernelEvent(input);
    return await sink.push([event]);
  } catch (error) {
    logger?.warn?.(`${WU_LIFECYCLE_SYNC_LOG_PREFIX} fail-open: ${getErrorMessage(error)}`);
    return {
      sent: WU_LIFECYCLE_SYNC_RESULT_DEFAULTS.SENT,
      accepted: WU_LIFECYCLE_SYNC_RESULT_DEFAULTS.ACCEPTED,
      skippedReason: WU_LIFECYCLE_SYNC_SKIPPED_REASONS.PUSH_FAILED
    };
  }
}

export {
  buildWuLifecycleKernelEvent,
  flushWuLifecycleSync
};
