import { EventEmitter } from "events";
import { logger } from "../../core/monitoring/logger.js";
import { LinearSyncEngine } from "./sync.js";
class LinearSyncManager extends EventEmitter {
  syncEngine;
  syncTimer;
  pendingSyncTimer;
  config;
  lastSyncTime = 0;
  syncInProgress = false;
  syncLockAcquired = 0;
  // Timestamp when lock was acquired
  SYNC_LOCK_TIMEOUT = 3e5;
  // 5 minutes max sync time
  taskStore;
  constructor(taskStore, authManager, config, projectRoot) {
    super();
    this.taskStore = taskStore;
    this.config = {
      ...config,
      autoSyncInterval: config.autoSyncInterval || 15,
      syncOnTaskChange: config.syncOnTaskChange !== false,
      syncOnSessionStart: config.syncOnSessionStart !== false,
      syncOnSessionEnd: config.syncOnSessionEnd !== false,
      debounceInterval: config.debounceInterval || 5e3
      // 5 seconds
    };
    this.syncEngine = new LinearSyncEngine(
      taskStore,
      authManager,
      config,
      projectRoot
    );
    this.setupEventListeners();
    this.setupPeriodicSync();
  }
  /**
   * Setup event listeners for automatic sync triggers
   */
  setupEventListeners() {
    if (this.config.syncOnTaskChange && this.taskStore) {
      this.taskStore.on("sync:needed", (changeType) => {
        logger.debug(`Task change detected: ${changeType}`);
        this.scheduleDebouncedSync();
      });
      this.taskStore.on("task:created", (task) => {
        logger.debug(`Task created: ${task.title}`);
      });
      this.taskStore.on("task:completed", (task) => {
        logger.debug(`Task completed: ${task.title}`);
      });
      logger.info("Task change sync enabled via EventEmitter");
    }
  }
  /**
   * Setup periodic sync timer
   */
  setupPeriodicSync() {
    if (!this.config.autoSync || !this.config.autoSyncInterval) {
      return;
    }
    if (this.syncTimer) {
      clearInterval(this.syncTimer);
    }
    const intervalMs = this.config.autoSyncInterval * 60 * 1e3;
    this.syncTimer = setInterval(() => {
      this.performSync("periodic");
    }, intervalMs);
    logger.info(
      `Periodic Linear sync enabled: every ${this.config.autoSyncInterval} minutes`
    );
  }
  /**
   * Schedule a debounced sync to avoid too frequent syncs
   */
  scheduleDebouncedSync() {
    if (!this.config.enabled) return;
    if (this.pendingSyncTimer) {
      clearTimeout(this.pendingSyncTimer);
    }
    this.pendingSyncTimer = setTimeout(() => {
      this.performSync("task-change");
    }, this.config.debounceInterval);
  }
  /**
   * Perform a sync operation
   */
  async performSync(trigger) {
    if (!this.config.enabled) {
      return {
        success: false,
        synced: { toLinear: 0, fromLinear: 0, updated: 0 },
        conflicts: [],
        errors: ["Sync is disabled"]
      };
    }
    if (this.syncInProgress) {
      logger.warn(`Linear sync already in progress, skipping ${trigger} sync`);
      return {
        success: false,
        synced: { toLinear: 0, fromLinear: 0, updated: 0 },
        conflicts: [],
        errors: ["Sync already in progress"]
      };
    }
    const now = Date.now();
    const timeSinceLastSync = now - this.lastSyncTime;
    const minInterval = 1e4;
    if (trigger !== "manual" && timeSinceLastSync < minInterval) {
      logger.debug(
        `Skipping ${trigger} sync, too soon since last sync (${timeSinceLastSync}ms ago)`
      );
      return {
        success: false,
        synced: { toLinear: 0, fromLinear: 0, updated: 0 },
        conflicts: [],
        errors: [
          `Too soon since last sync (wait ${minInterval - timeSinceLastSync}ms)`
        ]
      };
    }
    try {
      this.syncInProgress = true;
      this.emit("sync:started", { trigger });
      logger.info(`Starting Linear sync (trigger: ${trigger})`);
      const result = await this.syncEngine.sync();
      this.lastSyncTime = now;
      if (result.success) {
        logger.info(
          `Linear sync completed: ${result.synced.toLinear} to Linear, ${result.synced.fromLinear} from Linear, ${result.synced.updated} updated`
        );
        this.emit("sync:completed", { trigger, result });
      } else {
        logger.error(`Linear sync failed: ${result.errors.join(", ")}`);
        this.emit("sync:failed", { trigger, result });
      }
      return result;
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : String(error);
      logger.error(`Linear sync error: ${errorMessage}`);
      const result = {
        success: false,
        synced: { toLinear: 0, fromLinear: 0, updated: 0 },
        conflicts: [],
        errors: [errorMessage]
      };
      this.emit("sync:failed", { trigger, result, error });
      return result;
    } finally {
      this.syncInProgress = false;
    }
  }
  /**
   * Sync on session start
   */
  async syncOnStart() {
    if (this.config.syncOnSessionStart) {
      return await this.performSync("session-start");
    }
    return null;
  }
  /**
   * Sync on session end
   */
  async syncOnEnd() {
    if (this.config.syncOnSessionEnd) {
      return await this.performSync("session-end");
    }
    return null;
  }
  /**
   * Update sync configuration
   */
  updateConfig(newConfig) {
    this.config = { ...this.config, ...newConfig };
    this.syncEngine.updateConfig(newConfig);
    if (newConfig.autoSyncInterval !== void 0 || newConfig.autoSync !== void 0) {
      this.setupPeriodicSync();
    }
  }
  /**
   * Get sync status
   */
  getStatus() {
    const nextSyncTime = this.config.autoSync && this.config.autoSyncInterval ? this.lastSyncTime + this.config.autoSyncInterval * 60 * 1e3 : null;
    return {
      enabled: this.config.enabled,
      syncInProgress: this.syncInProgress,
      lastSyncTime: this.lastSyncTime,
      nextSyncTime,
      config: this.config
    };
  }
  /**
   * Stop all sync activities
   */
  stop() {
    if (this.syncTimer) {
      clearInterval(this.syncTimer);
      this.syncTimer = void 0;
    }
    if (this.pendingSyncTimer) {
      clearTimeout(this.pendingSyncTimer);
      this.pendingSyncTimer = void 0;
    }
    this.removeAllListeners();
    logger.info("Linear sync manager stopped");
  }
  /**
   * Force an immediate sync
   */
  async forceSync() {
    return await this.performSync("manual");
  }
}
const DEFAULT_SYNC_MANAGER_CONFIG = {
  enabled: true,
  direction: "bidirectional",
  autoSync: true,
  autoSyncInterval: 15,
  // minutes
  conflictResolution: "newest_wins",
  syncOnTaskChange: true,
  syncOnSessionStart: true,
  syncOnSessionEnd: true,
  debounceInterval: 5e3
  // 5 seconds
};
export {
  DEFAULT_SYNC_MANAGER_CONFIG,
  LinearSyncManager
};
//# sourceMappingURL=sync-manager.js.map
