import { PlatformError } from './errors.mjs';

export class LifecycleManager {
  #state = 'created';
  #hooks = [];

  register({ id, order = 100, start = async () => {}, stop = async () => {} }) {
    if (!id || this.#hooks.some(hook => hook.id === id)) {
      throw new PlatformError(`Ungültiger oder doppelter Lifecycle-Hook: ${id}`, { code: 'LIFECYCLE_HOOK_INVALID' });
    }
    this.#hooks.push({ id: String(id), order: Number(order) || 100, start, stop, state: 'registered' });
  }

  async start(context) {
    if (!['created', 'stopped'].includes(this.#state)) throw new PlatformError(`Kernel kann aus Zustand ${this.#state} nicht starten.`, { code: 'LIFECYCLE_STATE_INVALID' });
    this.#state = 'starting';
    const started = [];
    try {
      for (const hook of [...this.#hooks].sort((a, b) => a.order - b.order)) {
        hook.state = 'starting';
        await hook.start(context);
        hook.state = 'running';
        started.push(hook);
      }
      this.#state = 'running';
    } catch (error) {
      for (const hook of started.reverse()) {
        try { await hook.stop({ ...context, rollback: true }); } catch {}
        hook.state = 'stopped';
      }
      this.#state = 'failed';
      throw error;
    }
  }

  async stop(context) {
    if (!['running', 'starting'].includes(this.#state)) return;
    this.#state = 'stopping';
    for (const hook of [...this.#hooks].sort((a, b) => b.order - a.order)) {
      if (hook.state !== 'running') continue;
      try { await hook.stop(context); } finally { hook.state = 'stopped'; }
    }
    this.#state = 'stopped';
  }

  snapshot() {
    return { state: this.#state, hooks: this.#hooks.map(({ start: _s, stop: _t, ...hook }) => ({ ...hook })) };
  }
}
