local createLibTest = require('/apis/libtest');
local createVersion = require('/apis/libversion');

local testlib = createLibTest({ ... });

local counter = 0;

local function freshDirs()
  counter = counter + 1;
  local stateDir = '/libversion-test/state-' .. counter;
  local repoRoot = '/libversion-test/repo-' .. counter;
  fs.delete(stateDir);
  fs.delete(repoRoot);
  return stateDir, repoRoot;
end

local function writeJson(path, value)
  local dir = path:match('^(.*)/[^/]+$');
  if dir then fs.makeDir(dir); end
  local f = fs.open(path, 'w');
  f.write(textutils.serializeJSON(value));
  f.close();
end

testlib.test('forFile reads the version from the lock file', function()
  local stateDir, repoRoot = freshDirs();
  writeJson(stateDir .. '/ccpm.lock.json', {
    packages = {
      ['trapos-ai'] = {
        version = '0.4.2',
        files = { 'apis/libai.lua', 'programs/ai.lua' },
      },
      ['trapos-core'] = {
        version = '0.4.0',
        files = { 'apis/eventloop.lua' },
      },
    },
  });
  local v = createVersion({ stateDir = stateDir, repoRoot = repoRoot });
  testlib.assertEquals(v.forFile('/programs/ai.lua'), '0.4.2');
  testlib.assertEquals(v.forFile('programs/ai.lua'), '0.4.2');
  testlib.assertEquals(v.forFile('/apis/eventloop.lua'), '0.4.0');
end);

testlib.test('forFile falls back to packages/<name>/ccpm.json when no lock entry matches', function()
  local stateDir, repoRoot = freshDirs();
  writeJson(repoRoot .. '/packages/trapos-cloud/ccpm.json', {
    name = 'trapos-cloud',
    version = '0.2.1',
    files = { 'apis/libcloud.lua', 'programs/cloud.lua' },
  });
  writeJson(repoRoot .. '/packages/trapos-ui/ccpm.json', {
    name = 'trapos-ui',
    version = '0.2.2',
    files = { 'apis/libtui.lua' },
  });
  local v = createVersion({ stateDir = stateDir, repoRoot = repoRoot });
  testlib.assertEquals(v.forFile('/programs/cloud.lua'), '0.2.1');
  testlib.assertEquals(v.forFile('/apis/libtui.lua'), '0.2.2');
end);

testlib.test('forFile prefers the lock entry over the repo descriptor', function()
  local stateDir, repoRoot = freshDirs();
  writeJson(stateDir .. '/ccpm.lock.json', {
    packages = {
      ['trapos-ui'] = {
        version = '9.9.9',
        files = { 'programs/tuidemo.lua' },
      },
    },
  });
  writeJson(repoRoot .. '/packages/trapos-ui/ccpm.json', {
    name = 'trapos-ui',
    version = '0.2.1',
    files = { 'programs/tuidemo.lua' },
  });
  local v = createVersion({ stateDir = stateDir, repoRoot = repoRoot });
  testlib.assertEquals(v.forFile('/programs/tuidemo.lua'), '9.9.9');
end);

testlib.test('forFile returns "?" when neither source knows the file', function()
  local stateDir, repoRoot = freshDirs();
  local v = createVersion({ stateDir = stateDir, repoRoot = repoRoot });
  testlib.assertEquals(v.forFile('/programs/ghost.lua'), '?');
end);

testlib.test('forSelf resolves via shell.getRunningProgram', function()
  local stateDir, repoRoot = freshDirs();
  writeJson(stateDir .. '/ccpm.lock.json', {
    packages = {
      ['trapos-test'] = {
        version = '0.2.1',
        files = { 'programs/runtest.lua' },
      },
    },
  });
  local fakeShell = { getRunningProgram = function() return 'programs/runtest.lua'; end };
  local v = createVersion({ stateDir = stateDir, repoRoot = repoRoot, shell = fakeShell });
  testlib.assertEquals(v.forSelf(), '0.2.1');
end);

testlib.run();

