import {
  DEFAULT_POLL_INTERVAL_MS,
  GITHUB_CONNECTOR_ID,
  GITHUB_DEFAULT_POLL_INTERVAL_MS,
  GMAIL_CONNECTOR_ID,
  GMAIL_DEFAULT_POLL_INTERVAL_MS,
  GOOGLE_DRIVE_CONNECTOR_ID,
  NOTION_CONNECTOR_ID,
  NOTION_DEFAULT_POLL_INTERVAL_MS,
  createGitHubConnector,
  createGmailConnector,
  createGoogleDriveConnector,
  createNotionConnector,
  validateGitHubConfig,
  validateGmailConfig,
  validateGoogleDriveConfig,
  validateNotionConfig
} from "./chunk-L2IO2QPY.js";
import {
  readConnectorState,
  writeConnectorState
} from "./chunk-6TBWYBJ3.js";
import {
  runConnectorPollOnce
} from "./chunk-OZHRDTDX.js";

// src/live-connectors-runner.ts
function builtInLiveConnectorDefinitions(config) {
  return [
    {
      id: GOOGLE_DRIVE_CONNECTOR_ID,
      displayName: "Google Drive",
      enabled: config.googleDrive.enabled,
      pollIntervalMs: config.googleDrive.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS,
      rawConfig: config.googleDrive,
      createConnector: createGoogleDriveConnector,
      validateConfig: (raw) => validateGoogleDriveConfig(raw)
    },
    {
      id: NOTION_CONNECTOR_ID,
      displayName: "Notion",
      enabled: config.notion.enabled,
      pollIntervalMs: config.notion.pollIntervalMs ?? NOTION_DEFAULT_POLL_INTERVAL_MS,
      rawConfig: config.notion,
      createConnector: createNotionConnector,
      validateConfig: (raw) => validateNotionConfig(raw)
    },
    {
      id: GMAIL_CONNECTOR_ID,
      displayName: "Gmail",
      enabled: config.gmail.enabled,
      pollIntervalMs: config.gmail.pollIntervalMs ?? GMAIL_DEFAULT_POLL_INTERVAL_MS,
      rawConfig: config.gmail,
      createConnector: createGmailConnector,
      validateConfig: (raw) => validateGmailConfig(raw)
    },
    {
      id: GITHUB_CONNECTOR_ID,
      displayName: "GitHub",
      enabled: config.github.enabled,
      pollIntervalMs: config.github.pollIntervalMs ?? GITHUB_DEFAULT_POLL_INTERVAL_MS,
      rawConfig: config.github,
      createConnector: createGitHubConnector,
      validateConfig: (raw) => validateGitHubConfig(raw)
    }
  ];
}
function hasEnabledLiveConnector(config) {
  return config.googleDrive.enabled || config.notion.enabled || config.gmail.enabled || config.github.enabled;
}
async function runLiveConnectorsOnce(options) {
  const ranAt = resolveNow(options.now);
  const force = options.force === true;
  const definitions = options.definitions ?? builtInLiveConnectorDefinitions(options.connectors);
  const results = [];
  for (const definition of definitions) {
    const checkAt = resolveNow(options.now);
    if (!definition.enabled) {
      results.push(skipResult(definition, null, "disabled"));
      continue;
    }
    let state;
    try {
      state = await readConnectorState(options.memoryDir, definition.id);
    } catch (err) {
      results.push({
        id: definition.id,
        displayName: definition.displayName,
        enabled: true,
        ran: false,
        skippedReason: "state_read_error",
        docsImported: 0,
        error: err instanceof Error ? err.message : String(err),
        lastSyncAt: null,
        nextDueAt: null
      });
      continue;
    }
    if (!force && !isConnectorDue(state, definition.pollIntervalMs, checkAt)) {
      results.push(skipResult(definition, state, "not_due"));
      continue;
    }
    let validatedConfig;
    try {
      validatedConfig = definition.validateConfig(definition.rawConfig);
    } catch (err) {
      const message = err instanceof Error ? err.message : String(err);
      let stateWriteError;
      let writtenErrorState;
      const errorAt = resolveNow(options.now);
      try {
        writtenErrorState = await writeConnectorErrorState({
          memoryDir: options.memoryDir,
          connectorId: definition.id,
          state,
          error: message,
          now: errorAt
        });
      } catch (writeErr) {
        stateWriteError = writeErr instanceof Error ? writeErr.message : String(writeErr);
      }
      const reportedState = writtenErrorState ?? state;
      results.push({
        id: definition.id,
        displayName: definition.displayName,
        enabled: true,
        ran: false,
        skippedReason: "invalid_config",
        docsImported: 0,
        error: message,
        ...stateWriteError !== void 0 ? { stateWriteError } : {},
        lastSyncAt: reportedState?.lastSyncAt ?? null,
        nextDueAt: nextDueAt(reportedState, definition.pollIntervalMs)
      });
      continue;
    }
    let runResult;
    let lastStateWrittenAt;
    try {
      const connector = definition.createConnector();
      runResult = await runConnectorPollOnce({
        connectorId: definition.id,
        priorState: state,
        syncFn: (cursor) => connector.syncIncremental({
          cursor,
          config: validatedConfig,
          abortSignal: options.abortSignal
        }),
        ingestFn: options.ingestDocuments,
        writeCursorFn: (writeState) => {
          const writeAt = resolveNow(options.now);
          return writeConnectorState(options.memoryDir, definition.id, {
            id: definition.id,
            cursor: writeState.cursor,
            lastSyncAt: writeAt.toISOString(),
            lastSyncStatus: writeState.lastSyncStatus,
            ...writeState.lastSyncError !== void 0 ? { lastSyncError: writeState.lastSyncError } : {},
            totalDocsImported: writeState.totalDocsImported
          }).then(() => {
            lastStateWrittenAt = writeAt;
          });
        }
      });
    } catch (err) {
      const message = err instanceof Error ? err.message : String(err);
      let stateWriteError;
      let writtenErrorState;
      const errorAt = resolveNow(options.now);
      try {
        writtenErrorState = await writeConnectorErrorState({
          memoryDir: options.memoryDir,
          connectorId: definition.id,
          state,
          error: message,
          now: errorAt
        });
      } catch (writeErr) {
        stateWriteError = writeErr instanceof Error ? writeErr.message : String(writeErr);
      }
      const reportedState = writtenErrorState ?? state;
      results.push({
        id: definition.id,
        displayName: definition.displayName,
        enabled: true,
        ran: false,
        skippedReason: "connector_error",
        docsImported: 0,
        error: message,
        ...stateWriteError !== void 0 ? { stateWriteError } : {},
        lastSyncAt: reportedState?.lastSyncAt ?? null,
        nextDueAt: nextDueAt(reportedState, definition.pollIntervalMs)
      });
      continue;
    }
    results.push(
      runItemFromResult(
        definition,
        runResult,
        state,
        lastStateWrittenAt ?? resolveNow(options.now)
      )
    );
  }
  return {
    ranAt: ranAt.toISOString(),
    force,
    totalDocsImported: results.reduce((sum, item) => sum + item.docsImported, 0),
    ranCount: results.filter((item) => item.ran).length,
    skippedCount: results.filter((item) => !item.ran).length,
    errorCount: results.filter(
      (item) => item.error !== void 0 || item.stateWriteError !== void 0
    ).length,
    results
  };
}
function resolveNow(now) {
  return typeof now === "function" ? now() : now ?? /* @__PURE__ */ new Date();
}
function isConnectorDue(state, pollIntervalMs, now) {
  if (state?.lastSyncAt === null || state?.lastSyncAt === void 0) return true;
  const lastMs = Date.parse(state.lastSyncAt);
  if (!Number.isFinite(lastMs)) return true;
  return now.getTime() - lastMs >= Math.max(1, Math.floor(pollIntervalMs));
}
function nextDueAt(state, pollIntervalMs) {
  if (state?.lastSyncAt === null || state?.lastSyncAt === void 0) return null;
  const lastMs = Date.parse(state.lastSyncAt);
  if (!Number.isFinite(lastMs)) return null;
  return new Date(lastMs + Math.max(1, Math.floor(pollIntervalMs))).toISOString();
}
function skipResult(definition, state, skippedReason) {
  return {
    id: definition.id,
    displayName: definition.displayName,
    enabled: definition.enabled,
    ran: false,
    skippedReason,
    docsImported: 0,
    lastSyncAt: state?.lastSyncAt ?? null,
    nextDueAt: skippedReason === "not_due" ? nextDueAt(state, definition.pollIntervalMs) : null
  };
}
function runItemFromResult(definition, result, priorState, now) {
  const stateWriteFailed = result.stateWriteError !== void 0;
  const reportedLastSyncAt = stateWriteFailed ? priorState?.lastSyncAt ?? null : now.toISOString();
  const reportedNextDueAt = stateWriteFailed ? nextDueAt(priorState, definition.pollIntervalMs) : new Date(
    now.getTime() + Math.max(1, Math.floor(definition.pollIntervalMs))
  ).toISOString();
  return {
    id: definition.id,
    displayName: definition.displayName,
    enabled: definition.enabled,
    ran: true,
    docsImported: result.docsImported,
    ...result.error !== void 0 ? { error: result.error } : {},
    ...result.stateWriteError !== void 0 ? { stateWriteError: result.stateWriteError } : {},
    lastSyncAt: reportedLastSyncAt,
    nextDueAt: reportedNextDueAt
  };
}
async function writeConnectorErrorState(options) {
  return writeConnectorState(options.memoryDir, options.connectorId, {
    id: options.connectorId,
    cursor: options.state?.cursor ?? null,
    lastSyncAt: options.now.toISOString(),
    lastSyncStatus: "error",
    lastSyncError: options.error,
    totalDocsImported: options.state?.totalDocsImported ?? 0
  });
}

export {
  builtInLiveConnectorDefinitions,
  hasEnabledLiveConnector,
  runLiveConnectorsOnce
};
//# sourceMappingURL=chunk-ASIQZXYO.js.map