const test = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const os = require('node:os');
const path = require('node:path');

const {
  chooseLaunchWorkspace,
  describeProviderState,
  findCommandPath,
  parseProfileFile,
  resolveCommandCheckPath,
} = require('./state');

test('chooseLaunchWorkspace prefers the active workspace folder', () => {
  assert.deepEqual(
    chooseLaunchWorkspace({
      activeWorkspacePath: '/repo-b',
      workspacePaths: ['/repo-a', '/repo-b'],
    }),
    { workspacePath: '/repo-b', source: 'active-workspace' },
  );
});

test('chooseLaunchWorkspace falls back to the first workspace folder', () => {
  assert.deepEqual(
    chooseLaunchWorkspace({
      activeWorkspacePath: null,
      workspacePaths: ['/repo-a', '/repo-b'],
    }),
    { workspacePath: '/repo-a', source: 'first-workspace' },
  );
});

test('parseProfileFile returns null for invalid JSON', () => {
  assert.equal(parseProfileFile('{bad json}'), null);
});

test('parseProfileFile returns null for unsupported profiles', () => {
  assert.equal(
    parseProfileFile(
      JSON.stringify({
        profile: 'lmstudio',
        env: {},
        createdAt: '2026-04-03T00:00:00.000Z',
      }),
    ),
    null,
  );
});

test('parseProfileFile returns null when env is missing', () => {
  assert.equal(
    parseProfileFile(
      JSON.stringify({
        profile: 'openai',
        createdAt: '2026-04-03T00:00:00.000Z',
      }),
    ),
    null,
  );
});

test('parseProfileFile returns null when env is not an object', () => {
  assert.equal(
    parseProfileFile(
      JSON.stringify({
        profile: 'openai',
        env: ['OPENAI_MODEL=gpt-4o'],
        createdAt: '2026-04-03T00:00:00.000Z',
      }),
    ),
    null,
  );
});

test('resolveCommandCheckPath resolves workspace-relative executables', () => {
  assert.equal(
    resolveCommandCheckPath('./node_modules/.bin/openclaude', '/repo'),
    require('node:path').resolve('/repo', './node_modules/.bin/openclaude'),
  );
});

test('resolveCommandCheckPath leaves bare commands alone', () => {
  assert.equal(resolveCommandCheckPath('openclaude', '/repo'), null);
});

test('findCommandPath treats shell-like input as a literal executable name', t => {
  const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'openclaude-command-'));
  t.after(() => {
    fs.rmSync(tempDir, { recursive: true, force: true });
  });

  const commandName = process.platform === 'win32'
    ? 'openclaude & whoami'
    : 'openclaude && whoami';
  const executableName = process.platform === 'win32'
    ? `${commandName}.cmd`
    : commandName;
  const executablePath = path.join(tempDir, executableName);

  fs.writeFileSync(executablePath, process.platform === 'win32' ? '@echo off\r\n' : '#!/bin/sh\n');
  if (process.platform !== 'win32') {
    fs.chmodSync(executablePath, 0o755);
  }

  const resolvedPath = findCommandPath(commandName, {
    cwd: null,
    env: {
      PATH: tempDir,
      PATHEXT: '.CMD;.EXE',
    },
    platform: process.platform,
  });

  assert.ok(resolvedPath);
  assert.equal(resolvedPath.toLowerCase(), executablePath.toLowerCase());
});

test('describeProviderState uses saved profile when present', () => {
  assert.deepEqual(
    describeProviderState({
      shimEnabled: false,
      env: {},
      profile: {
        profile: 'ollama',
        env: { OPENAI_MODEL: 'llama3.2' },
        createdAt: '2026-04-03T00:00:00.000Z',
      },
    }),
    {
      label: 'Ollama',
      detail: 'llama3.2',
      source: 'profile',
    },
  );
});

test('describeProviderState reports LM Studio from openai profile base url', () => {
  assert.deepEqual(
    describeProviderState({
      shimEnabled: false,
      env: {},
      profile: {
        profile: 'openai',
        env: {
          OPENAI_BASE_URL: 'http://localhost:1234/v1',
          OPENAI_MODEL: 'qwen2.5-coder',
        },
        createdAt: '2026-04-03T00:00:00.000Z',
      },
    }),
    {
      label: 'LM Studio',
      detail: 'qwen2.5-coder',
      source: 'profile',
    },
  );
});

test('describeProviderState does not treat substring-matched OpenAI hosts as OpenAI', () => {
  assert.deepEqual(
    describeProviderState({
      shimEnabled: false,
      env: {
        CLAUDE_CODE_USE_OPENAI: '1',
        OPENAI_BASE_URL: 'https://evil.example/path/api.openai.com/v1',
        OPENAI_MODEL: 'gpt-4o',
      },
      profile: null,
    }),
    {
      label: 'OpenAI-compatible',
      detail: 'gpt-4o',
      source: 'env',
    },
  );
});

test('describeProviderState reports OpenAI when the parsed host is api.openai.com', () => {
  assert.deepEqual(
    describeProviderState({
      shimEnabled: false,
      env: {
        CLAUDE_CODE_USE_OPENAI: '1',
        OPENAI_BASE_URL: 'https://api.openai.com/v1',
        OPENAI_MODEL: 'gpt-4o',
      },
      profile: null,
    }),
    {
      label: 'OpenAI',
      detail: 'gpt-4o',
      source: 'env',
    },
  );
});

test('describeProviderState reports environment-backed provider details', () => {
  assert.deepEqual(
    describeProviderState({
      shimEnabled: false,
      env: {
        CLAUDE_CODE_USE_OPENAI: '1',
        OPENAI_BASE_URL: 'http://localhost:11434/v1',
        OPENAI_MODEL: 'llama3.2:3b',
      },
      profile: null,
    }),
    {
      label: 'Ollama',
      detail: 'llama3.2:3b',
      source: 'env',
    },
  );
});

test('describeProviderState reports unknown when only the shim is enabled', () => {
  assert.deepEqual(
    describeProviderState({
      shimEnabled: true,
      env: {},
      profile: null,
    }),
    {
      label: 'OpenAI-compatible (provider unknown)',
      detail: 'launch shim enabled',
      source: 'shim',
    },
  );
});

test('describeProviderState stays honest when nothing is configured', () => {
  assert.deepEqual(
    describeProviderState({
      shimEnabled: false,
      env: {},
      profile: null,
    }),
    {
      label: 'Unknown',
      detail: 'no saved profile or provider env detected',
      source: 'unknown',
    },
  );
});
