'use strict'
// Poller pause control — test-phase friendly on/off switches for the two
// network pollers that run inside targo-hub:
//
//   1. device  — GenieACS device-cache poll (~6000 ONTs every 5 min)
//   2. olt     — SNMP sweep of the 4 OLTs (every 5 min)
//
// State is persisted to data/poller-control.json so pauses survive container
// restarts. Each poller's tick function first calls isPaused('x') and bails
// early (logging a one-liner so you can see pauses in the container log).
//
// HTTP surface:
//   GET  /admin/pollers                   → { device: {paused, ...}, olt: {...} }
//   POST /admin/pollers { device, olt }   → updates the flags (partial ok)
//
// Auth alignment: same tier as /olt/config + /olt/poll (unauthenticated at
// hub layer — the ops SPA that calls these is already behind Authentik SSO
// at the edge). Don't expose this without that front door in place.

const fs = require('fs')
const path = require('path')
const cfg = require('./config')
const { log, json, parseBody } = require('./helpers')

const STATE_PATH = path.join(__dirname, '..', 'data', 'poller-control.json')
const DEFAULT_STATE = {
  device: { paused: false, lastChange: null, reason: '' },
  olt:    { paused: false, lastChange: null, reason: '' },
}

let state = { ...DEFAULT_STATE }

function load () {
  try {
    if (fs.existsSync(STATE_PATH)) {
      const raw = JSON.parse(fs.readFileSync(STATE_PATH, 'utf8'))
      state = {
        device: { ...DEFAULT_STATE.device, ...(raw.device || {}) },
        olt:    { ...DEFAULT_STATE.olt,    ...(raw.olt    || {}) },
      }
      if (state.device.paused || state.olt.paused) {
        log(`[poller-control] loaded — device.paused=${state.device.paused} olt.paused=${state.olt.paused}`)
      }
    }
  } catch (e) { log(`[poller-control] load failed: ${e.message} — using defaults`) }
}

function persist () {
  try {
    const dir = path.dirname(STATE_PATH)
    if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })
    fs.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2))
  } catch (e) { log(`[poller-control] persist failed: ${e.message}`) }
}

function isPaused (kind) {
  return !!(state[kind] && state[kind].paused)
}

function setPaused (kind, paused, reason = '') {
  if (!state[kind]) return false
  const prev = state[kind].paused
  state[kind].paused = !!paused
  state[kind].lastChange = new Date().toISOString()
  state[kind].reason = reason || ''
  if (prev !== state[kind].paused) {
    log(`[poller-control] ${kind} poller ${paused ? 'PAUSED' : 'RESUMED'}${reason ? ` — ${reason}` : ''}`)
  }
  persist()
  return true
}

function getState () {
  return JSON.parse(JSON.stringify(state))
}

// ── HTTP handler ────────────────────────────────────────────────────────────

async function handle (req, res, method, reqPath) {
  if (reqPath === '/admin/pollers' && method === 'GET') {
    return json(res, 200, getState())
  }

  if (reqPath === '/admin/pollers' && method === 'POST') {
    const body = await parseBody(req)
    const updates = {}
    for (const kind of ['device', 'olt']) {
      if (body && typeof body[kind] === 'object' && body[kind] !== null) {
        if (typeof body[kind].paused === 'boolean') {
          setPaused(kind, body[kind].paused, body[kind].reason || '')
          updates[kind] = true
        }
      } else if (body && typeof body[kind] === 'boolean') {
        // shorthand: { device: true, olt: false }
        setPaused(kind, body[kind])
        updates[kind] = true
      }
    }
    return json(res, 200, { ok: true, updates, state: getState() })
  }

  return json(res, 404, { error: 'not found' })
}

// initial load on require
load()

module.exports = { isPaused, setPaused, getState, handle, load }
