import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { mkdtempSync, rmSync, statSync, existsSync } from 'node:fs';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
import { saveCredentials, loadCredentials, deleteCredentials } from '../../src/auth/index.js';

let tempDir: string;

beforeEach(() => {
  tempDir = mkdtempSync(join(tmpdir(), 'mcpctl-auth-test-'));
});

afterEach(() => {
  rmSync(tempDir, { recursive: true, force: true });
});

describe('saveCredentials', () => {
  it('saves credentials file', () => {
    saveCredentials({ token: 'tok123', mcpdUrl: 'http://x:3100', user: 'alice@test.com' }, { configDir: tempDir });
    expect(existsSync(join(tempDir, 'credentials'))).toBe(true);
  });

  it('sets 0600 permissions', () => {
    saveCredentials({ token: 'tok123', mcpdUrl: 'http://x:3100', user: 'alice@test.com' }, { configDir: tempDir });
    const stat = statSync(join(tempDir, 'credentials'));
    expect(stat.mode & 0o777).toBe(0o600);
  });

  it('creates config dir if missing', () => {
    const nested = join(tempDir, 'sub', 'dir');
    saveCredentials({ token: 'tok', mcpdUrl: 'http://x:3100', user: 'bob' }, { configDir: nested });
    expect(existsSync(join(nested, 'credentials'))).toBe(true);
  });
});

describe('loadCredentials', () => {
  it('returns null when no credentials file', () => {
    expect(loadCredentials({ configDir: tempDir })).toBeNull();
  });

  it('round-trips credentials', () => {
    const creds = { token: 'tok456', mcpdUrl: 'http://remote:3100', user: 'charlie@test.com', expiresAt: '2099-01-01' };
    saveCredentials(creds, { configDir: tempDir });
    const loaded = loadCredentials({ configDir: tempDir });
    expect(loaded).toEqual(creds);
  });
});

describe('deleteCredentials', () => {
  it('returns false when no credentials file', () => {
    expect(deleteCredentials({ configDir: tempDir })).toBe(false);
  });

  it('deletes credentials file', () => {
    saveCredentials({ token: 'tok', mcpdUrl: 'http://x:3100', user: 'u' }, { configDir: tempDir });
    expect(deleteCredentials({ configDir: tempDir })).toBe(true);
    expect(existsSync(join(tempDir, 'credentials'))).toBe(false);
  });
});
