/**
 * Persist Command Tests
 *
 * Tests for the `ccs persist` CLI command including:
 * - Argument parsing
 * - API key masking
 * - Settings merge logic
 * - Backup management
 * - Error handling
 */

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

describe('Persist Command', () => {
  // =========================================================================
  // Argument Parsing Tests
  // =========================================================================
  describe('parseArgs', () => {
    /**
     * Simulates the argument parsing logic from persist-command.ts
     */
    function parseArgs(args) {
      const validPermissionModes = ['default', 'plan', 'acceptEdits', 'bypassPermissions'];
      const knownFlags = [
        '--yes',
        '-y',
        '--list-backups',
        '--restore',
        '--permission-mode',
        '--dangerously-skip-permissions',
        '--auto-approve',
        '--help',
        '-h',
      ];
      const result = {
        profile: undefined,
        yes: false,
        listBackups: false,
        restore: undefined,
        permissionMode: undefined,
        dangerouslySkipPermissions: false,
        parseError: undefined,
      };
      const unknownFlags = [];
      for (let i = 0; i < args.length; i++) {
        const arg = args[i];
        if (arg === '--yes' || arg === '-y') {
          result.yes = true;
        } else if (arg === '--help' || arg === '-h') {
          // Will be handled in main function
        } else if (arg === '--list-backups') {
          result.listBackups = true;
        } else if (arg === '--restore') {
          // Check if next arg is a timestamp (not a flag)
          const nextArg = args[i + 1];
          if (nextArg && !nextArg.startsWith('-')) {
            result.restore = nextArg;
            i++; // Skip next arg
          } else {
            result.restore = true; // Use latest
          }
        } else if (arg === '--permission-mode') {
          const nextArg = args[i + 1];
          if (!nextArg || nextArg.startsWith('-')) {
            result.parseError = 'Missing value for --permission-mode';
          } else if (!validPermissionModes.includes(nextArg)) {
            result.parseError = `Invalid --permission-mode "${nextArg}". Valid modes: ${validPermissionModes.join(', ')}`;
          } else {
            result.permissionMode = nextArg;
            i++; // Skip next arg
          }
        } else if (arg.startsWith('--permission-mode=')) {
          const mode = arg.split('=').slice(1).join('=');
          if (!mode.trim()) {
            result.parseError = 'Missing value for --permission-mode';
          } else if (!validPermissionModes.includes(mode)) {
            result.parseError = `Invalid --permission-mode "${mode}". Valid modes: ${validPermissionModes.join(', ')}`;
          } else {
            result.permissionMode = mode;
          }
        } else if (arg === '--dangerously-skip-permissions' || arg === '--auto-approve') {
          result.dangerouslySkipPermissions = true;
        } else if (!arg.startsWith('-') && !result.profile) {
          result.profile = arg;
        } else if (arg.startsWith('-')) {
          const known = knownFlags.some((flag) => arg === flag || arg.startsWith(`${flag}=`));
          if (!known) {
            unknownFlags.push(arg);
          }
        }
      }

      if (!result.parseError && unknownFlags.length > 0) {
        const unknownList = unknownFlags.map((flag) => `"${flag}"`).join(', ');
        result.parseError = `Unknown option(s): ${unknownList}. Run 'ccs persist --help' for usage.`;
      }

      if (!result.parseError && result.listBackups && result.restore) {
        result.parseError = '--list-backups cannot be used with --restore';
      }

      if (
        !result.parseError &&
        (result.listBackups || result.restore) &&
        (result.permissionMode || result.dangerouslySkipPermissions)
      ) {
        result.parseError =
          'Permission flags are not valid with backup operations. Use them only with ccs persist <profile>.';
      }

      return result;
    }

    function resolvePermissionMode(parsedArgs) {
      if (!parsedArgs.dangerouslySkipPermissions) {
        return parsedArgs.permissionMode;
      }

      if (parsedArgs.permissionMode && parsedArgs.permissionMode !== 'bypassPermissions') {
        throw new Error(
          '--dangerously-skip-permissions conflicts with --permission-mode. Use bypassPermissions or remove one flag.'
        );
      }

      return 'bypassPermissions';
    }

    it('parses profile name as first positional argument', () => {
      const result = parseArgs(['glm']);
      assert.strictEqual(result.profile, 'glm');
    });

    it('parses --yes flag', () => {
      const result = parseArgs(['glm', '--yes']);
      assert.strictEqual(result.yes, true);
      assert.strictEqual(result.profile, 'glm');
    });

    it('parses -y short flag', () => {
      const result = parseArgs(['gemini', '-y']);
      assert.strictEqual(result.yes, true);
      assert.strictEqual(result.profile, 'gemini');
    });

    it('parses flags before profile name', () => {
      const result = parseArgs(['--yes', 'kimi']);
      assert.strictEqual(result.yes, true);
      assert.strictEqual(result.profile, 'kimi');
    });

    it('handles no arguments', () => {
      const result = parseArgs([]);
      assert.strictEqual(result.profile, undefined);
      assert.strictEqual(result.yes, false);
    });

    it('rejects unknown flags with a clear parseError', () => {
      const result = parseArgs(['glm', '--unknown', '--yes']);
      assert.match(result.parseError, /Unknown option\(s\)/);
    });

    it('takes only first positional as profile', () => {
      const result = parseArgs(['first', 'second', 'third']);
      assert.strictEqual(result.profile, 'first');
    });

    it('parses --list-backups flag', () => {
      const result = parseArgs(['--list-backups']);
      assert.strictEqual(result.listBackups, true);
      assert.strictEqual(result.profile, undefined);
    });

    it('parses --restore flag without timestamp (use latest)', () => {
      const result = parseArgs(['--restore']);
      assert.strictEqual(result.restore, true);
    });

    it('parses --restore flag with timestamp', () => {
      const result = parseArgs(['--restore', '20260110_205324']);
      assert.strictEqual(result.restore, '20260110_205324');
    });

    it('parses --restore with --yes flag', () => {
      const result = parseArgs(['--restore', '--yes']);
      assert.strictEqual(result.restore, true);
      assert.strictEqual(result.yes, true);
    });

    it('parses --restore with timestamp and --yes flag', () => {
      const result = parseArgs(['--restore', '20260110_205324', '--yes']);
      assert.strictEqual(result.restore, '20260110_205324');
      assert.strictEqual(result.yes, true);
    });

    it('parses --permission-mode with valid mode', () => {
      const result = parseArgs(['glm', '--permission-mode', 'acceptEdits']);
      assert.strictEqual(result.profile, 'glm');
      assert.strictEqual(result.permissionMode, 'acceptEdits');
      assert.strictEqual(result.parseError, undefined);
    });

    it('parses --permission-mode=value syntax', () => {
      const result = parseArgs(['glm', '--permission-mode=bypassPermissions']);
      assert.strictEqual(result.permissionMode, 'bypassPermissions');
      assert.strictEqual(result.parseError, undefined);
    });

    it('sets parseError for invalid --permission-mode', () => {
      const result = parseArgs(['glm', '--permission-mode', 'invalid']);
      assert.match(result.parseError, /Invalid --permission-mode/);
    });

    it('sets parseError for missing --permission-mode value', () => {
      const result = parseArgs(['glm', '--permission-mode']);
      assert.strictEqual(result.parseError, 'Missing value for --permission-mode');
    });

    it('sets parseError for empty inline --permission-mode=', () => {
      const result = parseArgs(['glm', '--permission-mode=']);
      assert.strictEqual(result.parseError, 'Missing value for --permission-mode');
    });

    it('parses --dangerously-skip-permissions flag', () => {
      const result = parseArgs(['glm', '--dangerously-skip-permissions']);
      assert.strictEqual(result.dangerouslySkipPermissions, true);
    });

    it('parses --auto-approve as alias flag', () => {
      const result = parseArgs(['glm', '--auto-approve']);
      assert.strictEqual(result.dangerouslySkipPermissions, true);
    });

    it('handles both dangerous alias flags together', () => {
      const result = parseArgs(['glm', '--dangerously-skip-permissions', '--auto-approve']);
      assert.strictEqual(result.dangerouslySkipPermissions, true);
      assert.strictEqual(resolvePermissionMode(result), 'bypassPermissions');
    });

    ['acceptEdits', 'plan', 'default'].forEach((mode) => {
      it(`throws on conflict between dangerous mode and --permission-mode ${mode}`, () => {
        const parsed = parseArgs(['glm', '--permission-mode', mode, '--auto-approve']);

        assert.throws(
          () => resolvePermissionMode(parsed),
          /--dangerously-skip-permissions conflicts with --permission-mode/
        );
      });
    });

    it('allows dangerous mode with --permission-mode bypassPermissions', () => {
      const parsed = parseArgs([
        'glm',
        '--permission-mode',
        'bypassPermissions',
        '--dangerously-skip-permissions',
      ]);
      assert.strictEqual(resolvePermissionMode(parsed), 'bypassPermissions');
    });

    it('sets parseError when --list-backups and --restore are both provided', () => {
      const parsed = parseArgs(['--list-backups', '--restore']);
      assert.strictEqual(parsed.parseError, '--list-backups cannot be used with --restore');
    });

    it('sets parseError when permission flags are used with --restore', () => {
      const parsed = parseArgs(['--restore', '--auto-approve']);
      assert.match(parsed.parseError, /Permission flags are not valid with backup operations/);
    });

    it('sets parseError when permission flags are used with --list-backups', () => {
      const parsed = parseArgs(['--list-backups', '--permission-mode', 'plan']);
      assert.match(parsed.parseError, /Permission flags are not valid with backup operations/);
    });

    it('keeps test permission mode list exactly aligned with source constant', () => {
      const sourcePath = path.join(__dirname, '../../../src/commands/persist-command.ts');
      const sourceContent = fs.readFileSync(sourcePath, 'utf8');
      const match = sourceContent.match(/const VALID_PERMISSION_MODES = \[(.*?)\] as const/s);
      assert(match, 'Expected VALID_PERMISSION_MODES constant to exist');
      const sourceModes = [...match[1].matchAll(/'([^']+)'/g)].map((entry) => entry[1]).sort();
      const testModes = ['default', 'plan', 'acceptEdits', 'bypassPermissions'].sort();
      assert.deepStrictEqual(sourceModes, testModes);
    });

    it('accepts common option ordering permutations', () => {
      const cases = [
        ['glm', '--yes', '--permission-mode', 'plan'],
        ['--yes', 'glm', '--permission-mode=plan'],
        ['--permission-mode', 'plan', 'glm', '--yes'],
        ['--yes', '--permission-mode', 'plan', 'glm'],
      ];

      for (const input of cases) {
        const parsed = parseArgs(input);
        assert.strictEqual(parsed.parseError, undefined, `Expected no parseError for: ${input.join(' ')}`);
        assert.strictEqual(parsed.profile, 'glm');
        assert.strictEqual(parsed.yes, true);
        assert.strictEqual(parsed.permissionMode, 'plan');
      }
    });
  });

  // =========================================================================
  // API Key Masking Tests
  // =========================================================================
  describe('maskApiKey', () => {
    /**
     * Simulates the maskApiKey function from persist-command.ts
     */
    function maskApiKey(key) {
      if (key.length <= 12) {
        return '****';
      }
      return `${key.slice(0, 4)}...${key.slice(-4)}`;
    }

    it('masks keys showing first 4 and last 4 characters', () => {
      const result = maskApiKey('sk-1234567890abcdef');
      assert.strictEqual(result, 'sk-1...cdef');
    });

    it('returns **** for keys <= 12 characters', () => {
      assert.strictEqual(maskApiKey('123456789012'), '****');
      assert.strictEqual(maskApiKey('12345678901'), '****');
      assert.strictEqual(maskApiKey('short'), '****');
      assert.strictEqual(maskApiKey(''), '****');
    });

    it('handles exactly 13 character keys', () => {
      const result = maskApiKey('1234567890abc');
      assert.strictEqual(result, '1234...0abc');
    });

    it('handles long API keys', () => {
      const longKey = 'api_key_1234567890abcdefghijklmnopqrstuvwxyz';
      const result = maskApiKey(longKey);
      assert.strictEqual(result, 'api_...wxyz');
    });

    it('preserves special characters', () => {
      const key = '!@#$%^&*()_+-=[]{}';
      const result = maskApiKey(key);
      assert.strictEqual(result, '!@#$...[]{}');
    });
  });

  // =========================================================================
  // Settings Merge Tests
  // =========================================================================
  describe('Settings Merge Logic', () => {
    /**
     * Simulates the merge logic from persist-command.ts
     */
    function mergeSettings(existing, newEnv, permissionMode) {
      const existingEnv = existing.env || {};
      const merged = {
        ...existing,
        env: {
          ...existingEnv,
          ...newEnv,
        },
      };

      if (permissionMode) {
        const existingPermissions =
          existing.permissions && typeof existing.permissions === 'object'
            ? existing.permissions
            : {};
        merged.permissions = {
          ...existingPermissions,
          defaultMode: permissionMode,
        };
      }

      return merged;
    }

    it('merges env vars into empty settings', () => {
      const existing = {};
      const newEnv = { ANTHROPIC_BASE_URL: 'http://example.com' };
      const result = mergeSettings(existing, newEnv);
      assert.deepStrictEqual(result.env, newEnv);
    });

    it('preserves existing hooks', () => {
      const existing = {
        hooks: { PreToolUse: [{ matcher: 'WebSearch' }] },
      };
      const newEnv = { ANTHROPIC_MODEL: 'test' };
      const result = mergeSettings(existing, newEnv);
      assert.deepStrictEqual(result.hooks, existing.hooks);
    });

    it('preserves existing presets', () => {
      const existing = {
        presets: [{ name: 'test', default: 'model' }],
      };
      const newEnv = { ANTHROPIC_MODEL: 'test' };
      const result = mergeSettings(existing, newEnv);
      assert.deepStrictEqual(result.presets, existing.presets);
    });

    it('preserves other settings like model and alwaysThinkingEnabled', () => {
      const existing = {
        model: 'opus',
        alwaysThinkingEnabled: true,
      };
      const newEnv = { ANTHROPIC_MODEL: 'test' };
      const result = mergeSettings(existing, newEnv);
      assert.strictEqual(result.model, 'opus');
      assert.strictEqual(result.alwaysThinkingEnabled, true);
    });

    it('merges new env vars with existing env vars', () => {
      const existing = {
        env: { EXISTING_VAR: 'value' },
      };
      const newEnv = { NEW_VAR: 'new_value' };
      const result = mergeSettings(existing, newEnv);
      assert.strictEqual(result.env.EXISTING_VAR, 'value');
      assert.strictEqual(result.env.NEW_VAR, 'new_value');
    });

    it('overwrites existing env vars with new values', () => {
      const existing = {
        env: { ANTHROPIC_MODEL: 'old_model' },
      };
      const newEnv = { ANTHROPIC_MODEL: 'new_model' };
      const result = mergeSettings(existing, newEnv);
      assert.strictEqual(result.env.ANTHROPIC_MODEL, 'new_model');
    });

    it('handles complex settings with multiple fields', () => {
      const existing = {
        hooks: { PreToolUse: [] },
        presets: [],
        model: 'sonnet',
        env: { OLD_VAR: 'old' },
        customField: 'custom',
      };
      const newEnv = {
        ANTHROPIC_BASE_URL: 'http://test.com',
        ANTHROPIC_MODEL: 'test',
      };
      const result = mergeSettings(existing, newEnv);

      assert.deepStrictEqual(result.hooks, existing.hooks);
      assert.deepStrictEqual(result.presets, existing.presets);
      assert.strictEqual(result.model, 'sonnet');
      assert.strictEqual(result.customField, 'custom');
      assert.strictEqual(result.env.OLD_VAR, 'old');
      assert.strictEqual(result.env.ANTHROPIC_BASE_URL, 'http://test.com');
      assert.strictEqual(result.env.ANTHROPIC_MODEL, 'test');
    });

    it('sets permissions.defaultMode when permission mode is provided', () => {
      const existing = {
        hooks: { PreToolUse: [] },
      };
      const result = mergeSettings(existing, { ANTHROPIC_MODEL: 'test' }, 'acceptEdits');

      assert.strictEqual(result.permissions.defaultMode, 'acceptEdits');
      assert.deepStrictEqual(result.hooks, existing.hooks);
    });

    it('preserves existing permissions allow/deny when setting defaultMode', () => {
      const existing = {
        permissions: {
          allow: ['Bash(ls:*)'],
          deny: ['Bash(rm:*)'],
        },
      };
      const result = mergeSettings(existing, { ANTHROPIC_MODEL: 'test' }, 'bypassPermissions');

      assert.deepStrictEqual(result.permissions.allow, ['Bash(ls:*)']);
      assert.deepStrictEqual(result.permissions.deny, ['Bash(rm:*)']);
      assert.strictEqual(result.permissions.defaultMode, 'bypassPermissions');
    });
  });

  // =========================================================================
  // Backup Timestamp Tests
  // =========================================================================
  describe('Backup Timestamp Format', () => {
    /**
     * Simulates the timestamp generation from persist-command.ts
     */
    function generateTimestamp(date) {
      return (
        date.getFullYear().toString() +
        (date.getMonth() + 1).toString().padStart(2, '0') +
        date.getDate().toString().padStart(2, '0') +
        '_' +
        date.getHours().toString().padStart(2, '0') +
        date.getMinutes().toString().padStart(2, '0') +
        date.getSeconds().toString().padStart(2, '0')
      );
    }

    it('generates correct format YYYYMMDD_HHMMSS', () => {
      const date = new Date(2025, 0, 15, 10, 30, 45); // Jan 15, 2025 10:30:45
      const result = generateTimestamp(date);
      assert.strictEqual(result, '20250115_103045');
    });

    it('pads single digit months', () => {
      const date = new Date(2025, 0, 1, 0, 0, 0); // Jan 1
      const result = generateTimestamp(date);
      assert.match(result, /^202501/);
    });

    it('pads single digit days', () => {
      const date = new Date(2025, 11, 5, 0, 0, 0); // Dec 5
      const result = generateTimestamp(date);
      assert.match(result, /^20251205/);
    });

    it('pads single digit hours, minutes, seconds', () => {
      const date = new Date(2025, 5, 15, 1, 2, 3);
      const result = generateTimestamp(date);
      assert.strictEqual(result, '20250615_010203');
    });
  });

  // =========================================================================
  // Profile Type Detection Tests
  // =========================================================================
  describe('Profile Type Messages', () => {
    const profileTypes = {
      settings: 'API',
      cliproxy: 'CLIProxy',
      copilot: 'Copilot',
      account: 'Account (not supported)',
      default: 'Default (not supported)',
    };

    it('maps settings type to API', () => {
      assert.strictEqual(profileTypes.settings, 'API');
    });

    it('maps cliproxy type to CLIProxy', () => {
      assert.strictEqual(profileTypes.cliproxy, 'CLIProxy');
    });

    it('maps copilot type to Copilot', () => {
      assert.strictEqual(profileTypes.copilot, 'Copilot');
    });
  });

  // =========================================================================
  // Sensitive Key Detection Tests
  // =========================================================================
  describe('Sensitive Key Detection', () => {
    /**
     * Simulates the logic to detect sensitive keys for masking
     */
    function isSensitiveKey(key) {
      const sensitiveParts = new Set([
        'TOKEN',
        'KEY',
        'SECRET',
        'PASSWORD',
        'PASS',
        'AUTH',
        'CREDENTIAL',
        'PRIVATE',
        'ACCESS',
        'REFRESH',
        'APIKEY',
      ]);
      const withCamelCaseBoundaries = key.replace(/([a-z0-9])([A-Z])/g, '$1_$2');
      const parts = withCamelCaseBoundaries.toUpperCase().split(/[^A-Z0-9]+/).filter(Boolean);
      if (parts.some((part) => sensitiveParts.has(part))) {
        return true;
      }
      const compact = parts.join('');
      return (
        compact.includes('TOKEN') ||
        compact.includes('APIKEY') ||
        compact.includes('ACCESSKEY') ||
        compact.includes('AUTHKEY') ||
        compact.includes('SECRET') ||
        compact.includes('PASSWORD') ||
        compact.includes('CREDENTIAL')
      );
    }

    it('detects TOKEN in key name', () => {
      assert.strictEqual(isSensitiveKey('ANTHROPIC_AUTH_TOKEN'), true);
      assert.strictEqual(isSensitiveKey('ACCESS_TOKEN'), true);
    });

    it('detects KEY in key name', () => {
      assert.strictEqual(isSensitiveKey('API_KEY'), true);
      assert.strictEqual(isSensitiveKey('ANTHROPIC_API_KEY'), true);
    });

    it('detects SECRET in key name', () => {
      assert.strictEqual(isSensitiveKey('CLIENT_SECRET'), true);
      assert.strictEqual(isSensitiveKey('SECRET_KEY'), true);
    });

    it('does not flag non-sensitive keys', () => {
      assert.strictEqual(isSensitiveKey('ANTHROPIC_BASE_URL'), false);
      assert.strictEqual(isSensitiveKey('ANTHROPIC_MODEL'), false);
      assert.strictEqual(isSensitiveKey('DISABLE_TELEMETRY'), false);
    });

    it('detects lowercase and mixed-case sensitive keys', () => {
      assert.strictEqual(isSensitiveKey('anthropic_auth_token'), true);
      assert.strictEqual(isSensitiveKey('Api_Key'), true);
      assert.strictEqual(isSensitiveKey('clientSecret'), true);
    });

    it('detects additional secret families', () => {
      assert.strictEqual(isSensitiveKey('DB_PASSWORD'), true);
      assert.strictEqual(isSensitiveKey('refresh_token_value'), true);
      assert.strictEqual(isSensitiveKey('private_credential_blob'), true);
    });

    it('detects camelCase sensitive key variants', () => {
      assert.strictEqual(isSensitiveKey('accessKeyId'), true);
      assert.strictEqual(isSensitiveKey('authTokenValue'), true);
      assert.strictEqual(isSensitiveKey('apiKeyValue'), true);
    });
  });

  // =========================================================================
  // Help Text Coverage Tests
  // =========================================================================
  describe('Help Text Coverage', () => {
    const expectedOptions = ['--yes', '-y', '--help', '-h'];
    const expectedProfileTypes = ['API profiles', 'CLIProxy', 'Copilot', 'Account-based'];

    it('documents all CLI options', () => {
      expectedOptions.forEach((option) => {
        assert(typeof option === 'string', `Option ${option} should be a string`);
        assert(option.startsWith('-'), `Option ${option} should start with -`);
      });
    });

    it('documents all profile types', () => {
      expectedProfileTypes.forEach((type) => {
        assert(typeof type === 'string', `Profile type ${type} should be documented`);
      });
    });
  });

  // =========================================================================
  // Error Message Tests
  // =========================================================================
  describe('Error Messages', () => {
    it('account profile error message mentions CLAUDE_CONFIG_DIR', () => {
      const errorMessage =
        'Account profiles use CLAUDE_CONFIG_DIR isolation, not env vars.\n' +
        "Use 'ccs profileName' to run with this profile instead.";
      assert(errorMessage.includes('CLAUDE_CONFIG_DIR'));
      assert(errorMessage.includes('ccs profileName'));
    });

    it('no env vars error message includes profile name placeholder', () => {
      const profileName = 'test';
      const errorMessage = `Profile '${profileName}' has no env vars configured`;
      assert(errorMessage.includes(profileName));
    });
  });

  // =========================================================================
  // Backup File Parsing Tests
  // =========================================================================
  describe('Backup File Parsing', () => {
    const backupPattern = /^settings\.json\.backup\.(\d{8}_\d{6})$/;

    /**
     * Simulates parsing a backup filename into a BackupFile object
     */
    function parseBackupFile(filename, dir) {
      const match = filename.match(backupPattern);
      if (!match) return null;
      const timestamp = match[1];
      // Parse YYYYMMDD_HHMMSS
      const year = parseInt(timestamp.slice(0, 4));
      const month = parseInt(timestamp.slice(4, 6)) - 1;
      const day = parseInt(timestamp.slice(6, 8));
      const hour = parseInt(timestamp.slice(9, 11));
      const min = parseInt(timestamp.slice(11, 13));
      const sec = parseInt(timestamp.slice(13, 15));
      return {
        path: dir + '/' + filename,
        timestamp,
        date: new Date(year, month, day, hour, min, sec),
      };
    }

    it('matches valid backup filename pattern', () => {
      assert(backupPattern.test('settings.json.backup.20260110_205324'));
      assert(backupPattern.test('settings.json.backup.20250101_000000'));
    });

    it('rejects invalid backup filenames', () => {
      assert(!backupPattern.test('settings.json'));
      assert(!backupPattern.test('settings.json.backup'));
      assert(!backupPattern.test('settings.json.backup.invalid'));
      assert(!backupPattern.test('settings.json.backup.20260110'));
      assert(!backupPattern.test('other.json.backup.20260110_205324'));
    });

    it('parses backup file correctly', () => {
      const result = parseBackupFile('settings.json.backup.20260110_205324', '/home/user/.claude');
      assert.strictEqual(result.timestamp, '20260110_205324');
      assert.strictEqual(result.path, '/home/user/.claude/settings.json.backup.20260110_205324');
      assert.strictEqual(result.date.getFullYear(), 2026);
      assert.strictEqual(result.date.getMonth(), 0); // January
      assert.strictEqual(result.date.getDate(), 10);
      assert.strictEqual(result.date.getHours(), 20);
      assert.strictEqual(result.date.getMinutes(), 53);
      assert.strictEqual(result.date.getSeconds(), 24);
    });

    it('returns null for non-matching files', () => {
      const result = parseBackupFile('settings.json', '/home/user/.claude');
      assert.strictEqual(result, null);
    });

    it('sorts backup files by date descending (newest first)', () => {
      const files = [
        { timestamp: '20260109_100000', date: new Date(2026, 0, 9, 10, 0, 0) },
        { timestamp: '20260110_205324', date: new Date(2026, 0, 10, 20, 53, 24) },
        { timestamp: '20260110_100000', date: new Date(2026, 0, 10, 10, 0, 0) },
      ];
      const sorted = files.sort((a, b) => b.date.getTime() - a.date.getTime());
      assert.strictEqual(sorted[0].timestamp, '20260110_205324');
      assert.strictEqual(sorted[1].timestamp, '20260110_100000');
      assert.strictEqual(sorted[2].timestamp, '20260109_100000');
    });
  });

  // =========================================================================
  // Backup Restore Logic Tests
  // =========================================================================
  describe('Backup Restore Logic', () => {
    it('selects first backup when restore=true (latest)', () => {
      const backups = [{ timestamp: '20260110_205324' }, { timestamp: '20260110_100000' }];
      const restore = true;
      const selected = restore === true ? backups[0] : backups.find((b) => b.timestamp === restore);
      assert.strictEqual(selected.timestamp, '20260110_205324');
    });

    it('selects specific backup when restore is a timestamp', () => {
      const backups = [{ timestamp: '20260110_205324' }, { timestamp: '20260110_100000' }];
      const restore = '20260110_100000';
      const selected = restore === true ? backups[0] : backups.find((b) => b.timestamp === restore);
      assert.strictEqual(selected.timestamp, '20260110_100000');
    });

    it('returns undefined when timestamp not found', () => {
      const backups = [{ timestamp: '20260110_205324' }, { timestamp: '20260110_100000' }];
      const restore = '20260101_000000';
      const selected = restore === true ? backups[0] : backups.find((b) => b.timestamp === restore);
      assert.strictEqual(selected, undefined);
    });
  });
});
