/**
 * Plugin trust telemetry — per-machine install success/failure tracking.
 *
 * The review's ask: today plugin trust is binary (installed vs not).
 * Users can't tell which plugins are reliable. Track install outcomes
 * locally so the UI can say "0.94 trust (1,200/1,278 ok)" when the
 * user is about to install or look at a plugin.
 *
 * Local-only for now — privacy-preserving aggregation across users
 * (the review's full framing) would be a follow-up needing an
 * opt-in telemetry channel.
 */

import { mkdir, readFile, writeFile } from 'fs/promises'
import { homedir } from 'os'
import { join } from 'path'
import { logForDebugging } from '../../utils/debug.js'

const TRUST_FILE = join(homedir(), '.sandcode', 'plugin-trust.json')
// Below this score, badges render a warning glyph.
const WARN_THRESHOLD = 0.75

export interface PluginTrustRecord {
  id: string
  installs: number
  failures: number
  firstSeen: number
  lastUpdated: number
}

export interface PluginTrustState {
  version: 1
  plugins: Record<string, PluginTrustRecord>
}

export function createFreshRecord(id: string, now: number = Date.now()): PluginTrustRecord {
  return { id, installs: 0, failures: 0, firstSeen: now, lastUpdated: now }
}

export function createFreshState(): PluginTrustState {
  return { version: 1, plugins: {} }
}

/**
 * Trust score = installs / (installs + failures). Null when no
 * observations exist. Pure — testable without disk.
 */
export function computeTrustScore(record: PluginTrustRecord): number | null {
  const total = record.installs + record.failures
  if (total === 0) return null
  return record.installs / total
}

/**
 * Return a new record with the given outcome merged in. Pure.
 */
export function mergeInstallResult(
  record: PluginTrustRecord,
  success: boolean,
  now: number,
): PluginTrustRecord {
  return {
    ...record,
    installs: record.installs + (success ? 1 : 0),
    failures: record.failures + (success ? 0 : 1),
    lastUpdated: now,
  }
}

export function formatPluginTrustBadge(record: PluginTrustRecord): string {
  const total = record.installs + record.failures
  if (total === 0) return 'new (no install history)'
  const score = computeTrustScore(record)!
  const pct = Math.round(score * 100)
  const warn = score < WARN_THRESHOLD ? '\u26a0 ' : ''
  return `${warn}${pct}% trust (${record.installs}/${total} ok)`
}

async function loadState(): Promise<PluginTrustState> {
  try {
    const content = await readFile(TRUST_FILE, 'utf-8')
    const parsed = JSON.parse(content) as PluginTrustState
    if (parsed.version === 1) return parsed
  } catch {
    // File missing or invalid — fall through
  }
  return createFreshState()
}

async function saveState(state: PluginTrustState): Promise<void> {
  try {
    await mkdir(join(homedir(), '.sandcode'), { recursive: true })
    await writeFile(TRUST_FILE, JSON.stringify(state, null, 2), 'utf-8')
  } catch (e) {
    logForDebugging(`Failed to save plugin trust: ${String(e)}`)
  }
}

/**
 * Record an install outcome. Best-effort — disk errors are logged but
 * never block the caller.
 */
export async function recordPluginInstall(pluginId: string, success: boolean): Promise<void> {
  try {
    const state = await loadState()
    const now = Date.now()
    const existing = state.plugins[pluginId] ?? createFreshRecord(pluginId, now)
    state.plugins[pluginId] = mergeInstallResult(existing, success, now)
    await saveState(state)
  } catch (e) {
    logForDebugging(`recordPluginInstall failed: ${String(e)}`)
  }
}

export async function getPluginTrust(pluginId: string): Promise<PluginTrustRecord | null> {
  const state = await loadState()
  return state.plugins[pluginId] ?? null
}

export async function getAllPluginTrust(): Promise<PluginTrustRecord[]> {
  const state = await loadState()
  return Object.values(state.plugins)
}
