/**
 * Persistent consent store for remote telemetry upload.
 *
 * State is stored in $MOSAIC_HOME/telemetry.json (not inside the markdown
 * config files — those are template-rendered and would lose structured data).
 *
 * Schema:
 *   {
 *     remoteEnabled: boolean,
 *     optedInAt:     string | null,   // ISO timestamp
 *     optedOutAt:    string | null,   // ISO timestamp
 *     lastUploadAt:  string | null    // ISO timestamp
 *   }
 */

import { existsSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
import { atomicWrite } from '../platform/file-ops.js';
import { DEFAULT_MOSAIC_HOME } from '../constants.js';

export interface TelemetryConsent {
  remoteEnabled: boolean;
  optedInAt: string | null;
  optedOutAt: string | null;
  lastUploadAt: string | null;
}

const TELEMETRY_FILE = 'telemetry.json';

const DEFAULT_CONSENT: TelemetryConsent = {
  remoteEnabled: false,
  optedInAt: null,
  optedOutAt: null,
  lastUploadAt: null,
};

function consentFilePath(mosaicHome?: string): string {
  return join(mosaicHome ?? getMosaicHome(), TELEMETRY_FILE);
}

function getMosaicHome(): string {
  return process.env['MOSAIC_HOME'] ?? DEFAULT_MOSAIC_HOME;
}

/**
 * Read the current consent state. Returns defaults if file doesn't exist.
 */
export function readConsent(mosaicHome?: string): TelemetryConsent {
  const filePath = consentFilePath(mosaicHome);
  if (!existsSync(filePath)) {
    return { ...DEFAULT_CONSENT };
  }
  try {
    const raw = readFileSync(filePath, 'utf-8');
    const parsed = JSON.parse(raw) as Partial<TelemetryConsent>;
    return {
      remoteEnabled: parsed.remoteEnabled ?? false,
      optedInAt: parsed.optedInAt ?? null,
      optedOutAt: parsed.optedOutAt ?? null,
      lastUploadAt: parsed.lastUploadAt ?? null,
    };
  } catch {
    return { ...DEFAULT_CONSENT };
  }
}

/**
 * Persist a full or partial consent update.
 */
export function writeConsent(update: Partial<TelemetryConsent>, mosaicHome?: string): void {
  const current = readConsent(mosaicHome);
  const next: TelemetryConsent = { ...current, ...update };
  atomicWrite(consentFilePath(mosaicHome), JSON.stringify(next, null, 2) + '\n');
}

/**
 * Mark opt-in: enable remote upload and record timestamp.
 */
export function optIn(mosaicHome?: string): TelemetryConsent {
  const now = new Date().toISOString();
  const next: TelemetryConsent = {
    remoteEnabled: true,
    optedInAt: now,
    optedOutAt: null,
    lastUploadAt: readConsent(mosaicHome).lastUploadAt,
  };
  writeConsent(next, mosaicHome);
  return next;
}

/**
 * Mark opt-out: disable remote upload and record timestamp.
 */
export function optOut(mosaicHome?: string): TelemetryConsent {
  const now = new Date().toISOString();
  const current = readConsent(mosaicHome);
  const next: TelemetryConsent = {
    remoteEnabled: false,
    optedInAt: current.optedInAt,
    optedOutAt: now,
    lastUploadAt: current.lastUploadAt,
  };
  writeConsent(next, mosaicHome);
  return next;
}

/**
 * Record a successful upload timestamp.
 */
export function recordUpload(mosaicHome?: string): void {
  writeConsent({ lastUploadAt: new Date().toISOString() }, mosaicHome);
}
