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._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._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._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);
    });
  });
});
