'use strict';

const crypto = require('crypto');
const fs = require('fs');
const os = require('os');
const path = require('path');
const { normalizeBindHost } = require('./transport-security');

const CONFIG_DIR = process.env.CTM_DATA_DIR || path.join(process.env.HOME, '.walle', 'data');
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
const PORT = parseInt(process.env.CTM_PORT || '3456', 10);
const WALLE_PORT = parseInt(process.env.WALL_E_PORT || String(PORT + 1), 10);
const HOST_DECISION = normalizeBindHost(process.env.CTM_HOST || '127.0.0.1');
if (!HOST_DECISION.ok) {
  console.warn(`[server-config] Ignoring unsafe CTM_HOST=${JSON.stringify(process.env.CTM_HOST || '')}: ${HOST_DECISION.message}`);
}
const HOST = HOST_DECISION.ok ? HOST_DECISION.host : '127.0.0.1';
const HOSTNAME = os.hostname();

function loadConfig() {
  if (!fs.existsSync(CONFIG_DIR)) fs.mkdirSync(CONFIG_DIR, { recursive: true });
  // Local cache avoids Dropbox EAGAIN storms during disk pressure.
  const localCache = path.join(process.env.HOME, '.walle', 'config-cache.json');
  try { fs.mkdirSync(path.dirname(localCache), { recursive: true }); } catch {}

  try {
    if (fs.existsSync(CONFIG_FILE)) {
      const config = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
      try { fs.writeFileSync(localCache, JSON.stringify(config, null, 2)); fs.chmodSync(localCache, 0o600); } catch {}
      return config;
    }
  } catch (e) {
    console.error(`[loadConfig] Failed to read ${CONFIG_FILE}: ${e.code || e.message}, trying local cache...`);
    try {
      if (fs.existsSync(localCache)) return JSON.parse(fs.readFileSync(localCache, 'utf8'));
    } catch (e2) {
      console.error(`[loadConfig] Local cache also failed: ${e2.message}`);
    }
    throw e;
  }

  const config = {
    token: crypto.randomBytes(32).toString('hex'),
    walleToken: crypto.randomBytes(32).toString('hex'),
  };
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
  fs.chmodSync(CONFIG_FILE, 0o600);
  try { fs.writeFileSync(localCache, JSON.stringify(config, null, 2)); fs.chmodSync(localCache, 0o600); } catch {}
  return config;
}

/**
 * Returns the shared Wall-E API token, generating + persisting one if absent
 * from an existing config (handles configs created before walleToken existed).
 */
function ensureWalleToken() {
  const config = loadConfig();
  if (config.walleToken) return config.walleToken;
  config.walleToken = crypto.randomBytes(32).toString('hex');
  try {
    fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
    fs.chmodSync(CONFIG_FILE, 0o600);
  } catch (e) {
    console.error(`[server-config] Failed to persist walleToken to ${CONFIG_FILE}: ${e.message}`);
  }
  return config.walleToken;
}

module.exports = {
  CONFIG_DIR,
  CONFIG_FILE,
  HOST,
  HOSTNAME,
  PORT,
  WALLE_PORT,
  loadConfig,
  ensureWalleToken,
};
