import {CodeOwnerService} from './code-owners-service.js';
import {
  RequestPayload,
  RestPluginApi,
} from '@gerritcodereview/typescript-api/rest.js';
import {
  ChangeInfo,
  HttpMethod,
} from '@gerritcodereview/typescript-api/rest-api.js';
import {SuggestionsType} from './code-owners-model.js';
import {assert} from '@open-wc/testing';

function flush() {
  return new Promise((resolve, _reject) => {
    setTimeout(resolve, 0);
  });
}

suite('code owners service tests', () => {
  let codeOwnersService: CodeOwnerService;
  const fakeRestApi = {
    send(
      _method: HttpMethod,
      _url: string,
      _payload?: RequestPayload,
      _errFn?: ErrorCallback,
      _contentType?: string
    ) {
      return Promise.resolve({});
    },
    getLoggedIn() {
      return Promise.resolve(true);
    },
    getAccount() {
      return Promise.resolve({email: 'someone@google.com'});
    },
  } as unknown as RestPluginApi;

  const fakeStatus = {
    // fake data with fake files
    patch_set_number: 1,
    file_code_owner_statuses: [
      {
        new_path_status: {
          path: 'a.js',
          status: 'INSUFFICIENT_REVIEWERS',
        },
      },
      {
        new_path_status: {
          path: 'b.js',
          status: 'INSUFFICIENT_REVIEWERS',
        },
      },
      {
        new_path_status: {
          path: 'c.ts',
          status: 'INSUFFICIENT_REVIEWERS',
        },
      },
      {
        change_type: 'RENAMED',
        old_path_status: {
          path: 'd.ts',
          status: 'INSUFFICIENT_REVIEWERS',
        },
        new_path_status: {
          path: 'd_edit.ts',
          status: 'INSUFFICIENT_REVIEWERS',
        },
      },
      {
        new_path_status: {
          path: 'e.ts',
          status: 'PENDING',
        },
      },
      {
        new_path_status: {
          path: 'f.ts',
          status: 'PENDING',
        },
      },
      {
        new_path_status: {
          path: 'g.ts',
          status: 'PENDING',
        },
      },
    ],
  };
  const fakeChange = {
    project: 'test',
    branch: 'main',
    _number: '123',
    revisions: {
      a: {
        _number: 1,
      },
    },
    current_revision: 'a',
  } as unknown as ChangeInfo;

  let getApiStub: sinon.SinonStub;

  setup(() => {
    getApiStub = sinon.stub(fakeRestApi, 'send');
    getApiStub.returns(Promise.resolve({}));
  });

  teardown(() => {
    getApiStub.reset();
    CodeOwnerService.reset();
    sinon.restore();
  });

  suite('basic api request tests', () => {
    setup(async () => {
      getApiStub
        .withArgs(
          sinon.match.any,
          `/changes/${fakeChange.project}~${fakeChange._number}/code_owners.status?limit=100000`,
          sinon.match.any,
          sinon.match.any
        )
        .returns(Promise.resolve(fakeStatus));
      codeOwnersService = CodeOwnerService.getOwnerService(fakeRestApi, {
        ...fakeChange,
      });
      await flush();
    });

    test('getOwnerService - same change returns the same instance', () => {
      assert.equal(
        CodeOwnerService.getOwnerService(fakeRestApi, fakeChange),
        CodeOwnerService.getOwnerService(fakeRestApi, fakeChange)
      );
    });

    test('return a new instance when change changed', () => {
      assert.notEqual(
        CodeOwnerService.getOwnerService(fakeRestApi, {...fakeChange}),
        CodeOwnerService.getOwnerService(fakeRestApi, {...fakeChange})
      );
    });

    test('should fetch status after init', () => {
      assert.isTrue(getApiStub.called);
      assert.equal(
        getApiStub.lastCall.args[1],
        `/changes/${fakeChange.project}~${fakeChange._number}/code_owners.status?limit=100000`
      );
    });

    test('getSuggestion should kickoff the fetch', async () => {
      assert.equal(getApiStub.callCount, 2);
      getApiStub.resetHistory();
      await codeOwnersService.getSuggestedOwners(
        SuggestionsType.ALL_SUGGESTIONS
      );
      // 8 requests for getting file owners
      assert.equal(getApiStub.callCount, 8);
    });

    test('approved status calculation', async () => {
      const approved = await codeOwnersService.areAllFilesApproved();
      assert.equal(approved, false);
    });
  });

  suite('getOwnedPaths', () => {
    async function setupBranchConfig(disabled: boolean | undefined) {
      getApiStub
        .withArgs(
          sinon.match.any,
          `/projects/${fakeChange.project}/branches/` +
            `${fakeChange.branch}/code_owners.branch_config`,
          sinon.match.any,
          sinon.match.any
        )
        .returns(Promise.resolve({disabled}));
      codeOwnersService = CodeOwnerService.getOwnerService(fakeRestApi, {
        ...fakeChange,
      });
      await flush();
      getApiStub.resetHistory();
    }
    test('should not fetch if disabled', async () => {
      await setupBranchConfig(true);

      await codeOwnersService.getOwnedPaths();
      assert.equal(getApiStub.callCount, 0);
    });

    test('should fetch if enabled', async () => {
      await setupBranchConfig(false);

      await codeOwnersService.getOwnedPaths();
      assert.equal(getApiStub.callCount, 1);
    });

    test('should fetch if enabled by default', async () => {
      await setupBranchConfig(undefined);

      await codeOwnersService.getOwnedPaths();
      assert.equal(getApiStub.callCount, 1);
    });
  });

  suite('all approved case', () => {
    setup(async () => {
      getApiStub
        .withArgs(
          sinon.match.any,
          `/changes/${fakeChange.project}~${fakeChange._number}/code_owners.status?limit=100000`,
          sinon.match.any,
          sinon.match.any
        )
        .returns(
          Promise.resolve({
            // fake data with fake files
            patch_set_number: 1,
            file_code_owner_statuses: [
              {
                new_path_status: {
                  path: 'a.js',
                  status: 'APPROVED',
                },
              },
              {
                new_path_status: {
                  path: 'b.js',
                  status: 'APPROVED',
                },
              },
              {
                old_path_status: {
                  path: 'd.js',
                  status: 'APPROVED',
                },
                change_type: 'DELETED',
              },
            ],
          })
        );

      codeOwnersService = CodeOwnerService.getOwnerService(fakeRestApi, {
        ...fakeChange,
      });
      await flush();
    });

    test('approved status calculation', async () => {
      const approved = await codeOwnersService.areAllFilesApproved();
      assert.equal(approved, true);
    });
  });
});
