/**
 * Identidades locales.
 *
 * Cada identidad vive en su propio directorio ~/.<cuenta>, con su secret, su base
 * de datos y sus blobs. Cual esta activa lo decide ssb_config.js al arrancar:
 * primero OASIS_ACCOUNT, y si no, el fichero que escribe setActive().
 *
 * Aqui no se cambia de identidad en caliente: medio Oasis captura la referencia al
 * sbot al cargarse, asi que cambiarla con el proceso vivo dejaria modulos hablando
 * con la identidad anterior. El cambio se aplica al reiniciar.
 */

const fs = require('fs');
const path = require('path');
const os = require('os');

// mismo criterio que ssb_config.js: este nombre acaba en rutas de fichero
const ACCOUNT_RE = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,31}$/;
const ACTIVE_FILE = path.join(__dirname, '..', 'configs', 'active-account');

const isValid = (name) => typeof name === 'string' && ACCOUNT_RE.test(name);

/** Cuenta anotada como activa, o null si no hay ninguna anotada. */
const readActive = () => {
  try {
    const raw = fs.readFileSync(ACTIVE_FILE, 'utf8').trim();
    return isValid(raw) ? raw : null;
  } catch (_) { return null; }
};

/** Anota cual sera la cuenta activa en el proximo arranque. */
const setActive = (name) => {
  if (!isValid(name)) throw new Error('nombre de cuenta no valido');
  fs.mkdirSync(path.dirname(ACTIVE_FILE), { recursive: true });
  fs.writeFileSync(ACTIVE_FILE, name, { mode: 0o600 });
  return name;
};

/** Directorio de una cuenta. */
const dirOf = (name) => path.join(os.homedir(), `.${name}`);

/**
 * Identidades que existen en el disco: directorios ~/.<algo> con un secret dentro.
 * El secret es lo que hace que un directorio sea una identidad y no otra cosa.
 */
const list = () => {
  let entries = [];
  try {
    entries = fs.readdirSync(os.homedir(), { withFileTypes: true });
  } catch (_) { return []; }

  return entries
    .filter((e) => e.isDirectory() && e.name.startsWith('.'))
    .map((e) => e.name.slice(1))
    .filter(isValid)
    .filter((name) => {
      try { return fs.statSync(path.join(dirOf(name), 'secret')).isFile(); }
      catch (_) { return false; }
    })
    .sort();
};

/** Identidad publica (@...) de una cuenta, leyendo su secret. Null si no se puede. */
const feedIdOf = (name) => {
  if (!isValid(name)) return null;
  try {
    const raw = fs.readFileSync(path.join(dirOf(name), 'secret'), 'utf8');
    const clean = raw.split('\n').filter((l) => !l.trim().startsWith('#')).join('\n');
    const id = JSON.parse(clean).id;
    return typeof id === 'string' ? id : null;
  } catch (_) { return null; }
};

module.exports = { isValid, list, readActive, setActive, feedIdOf, dirOf, ACTIVE_FILE };
