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

const {
  resolveTier,
  promoteJobToProject,
} = require('./okf-scope');

test('resolveTier prefers job over project over global', () => {
  const scope = {
    global: { tier: 'global-tier' },
    projects: {
      alpha: {
        tier: 'project-tier',
        jobs: {
          build: { tier: 'job-tier' },
        },
      },
    },
  };

  assert.deepEqual(resolveTier(scope, { project: 'alpha', job: 'build' }), {
    tier: 'job-tier',
    source: 'job',
    project: 'alpha',
    job: 'build',
  });
  assert.deepEqual(resolveTier(scope, { project: 'alpha', job: 'test' }), {
    tier: 'project-tier',
    source: 'project',
    project: 'alpha',
    job: 'test',
  });
  assert.deepEqual(resolveTier(scope, { project: 'beta', job: 'lint' }), {
    tier: 'global-tier',
    source: 'global',
    project: 'beta',
    job: 'lint',
  });
});

test('resolveTier supports objectless lookups and explicit fallback default', () => {
  assert.deepEqual(resolveTier({}, { project: 'alpha', job: 'build', defaultTier: 'regular' }), {
    tier: 'regular',
    source: 'default',
    project: 'alpha',
    job: 'build',
  });
});

test('promoteJobToProject moves the resolved job tier to project scope and removes the job override', () => {
  const scope = {
    global: { tier: 'global-tier' },
    projects: {
      alpha: {
        tier: 'project-tier',
        jobs: {
          build: { tier: 'job-tier', retries: 2 },
          test: { tier: 'project-tier' },
        },
      },
    },
  };

  const result = promoteJobToProject(scope, { project: 'alpha', job: 'build' });

  assert.equal(result.promoted, true);
  assert.equal(result.tier, 'job-tier');
  assert.equal(result.scope.projects.alpha.tier, 'job-tier');
  assert.deepEqual(result.scope.projects.alpha.jobs.build, { retries: 2 });
  assert.deepEqual(result.scope.projects.alpha.jobs.test, { tier: 'project-tier' });
  assert.equal(scope.projects.alpha.tier, 'project-tier');
  assert.equal(scope.projects.alpha.jobs.build.tier, 'job-tier');
});

test('promoteJobToProject creates missing project containers from resolved defaults', () => {
  const result = promoteJobToProject(
    { global: { tier: 'global-tier' } },
    { project: 'alpha', job: 'build' },
  );

  assert.equal(result.promoted, true);
  assert.deepEqual(result.scope, {
    global: { tier: 'global-tier' },
    projects: {
      alpha: {
        tier: 'global-tier',
        jobs: {},
      },
    },
  });
});

test('promoteJobToProject is a no-op when the job already resolves from project scope', () => {
  const scope = {
    global: { tier: 'global-tier' },
    projects: {
      alpha: {
        tier: 'project-tier',
        jobs: {
          build: { retries: 2 },
        },
      },
    },
  };

  const result = promoteJobToProject(scope, { project: 'alpha', job: 'build' });

  assert.equal(result.promoted, false);
  assert.equal(result.reason, 'already-project');
  assert.deepEqual(result.scope, scope);
});
