/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { AutoPollingService } from './auto-polling.service';
import { TestBed, fakeAsync, tick } from '@angular/core/testing';
import { SearchService } from 'app/service/search.service';
import { Subject, of, throwError } from 'rxjs';
import { QueryBuilder } from '../query-builder';
import { SearchResponse } from 'app/model/search-response';
import { SearchRequest } from 'app/model/search-request';
import { Spy } from 'jasmine-core';
import { DialogService } from 'app/service/dialog.service';
import { RestError } from 'app/model/rest-error';
import { DialogType } from 'app/model/dialog-type';
import { RefreshInterval } from 'app/alerts/configure-rows/configure-rows-enums';

const DEFAULT_POLLING_INTERVAL = RefreshInterval.TEN_MIN;

class QueryBuilderFake {
  private _filter = '';
  query: '*'

  addOrUpdateFilter() {};

  setFilter(filter: string): void {
    this._filter = filter;
  };

  get searchRequest(): SearchRequest {
    return {
      query: this._filter,
      fields: [],
      size: 2,
      indices: [],
      from: 0,
      sort: [],
      facetFields: [],
    };
  };
}

describe('AutoPollingService', () => {

  let autoPollingService: AutoPollingService;
  let searchServiceFake: SearchService;

  function getIntervalInMS(): number {
    return autoPollingService.getInterval() * 1000;
  }

  beforeEach(() => {
    localStorage.getItem = () => null;
    localStorage.setItem = () => {};

    TestBed.configureTestingModule({
      providers: [
        AutoPollingService,
        { provide: DialogService, useClass: () => {} },
        { provide: SearchService, useClass: () => { return {
          search: () => of(new SearchResponse()),
        } } },
        { provide: QueryBuilder, useClass: QueryBuilderFake },
      ]
    });

    autoPollingService = TestBed.get(AutoPollingService);
    searchServiceFake = TestBed.get(SearchService);
  });

  afterEach(() => {
    autoPollingService.onDestroy();
  });


  describe('polling basics', () => {
    it('should mark polling as active after start', () => {
      autoPollingService.start();
      expect(autoPollingService.getIsPollingActive()).toBe(true);
    });

    it('should mark polling as inactive after stop', () => {
      autoPollingService.start();
      expect(autoPollingService.getIsPollingActive()).toBe(true);

      autoPollingService.stop();
      expect(autoPollingService.getIsPollingActive()).toBe(false);
    });

    it('should send an initial request on start', () => {
      spyOn(searchServiceFake, 'search').and.callThrough();

      autoPollingService.start();

      expect(searchServiceFake.search).toHaveBeenCalled();
    });

    it('should broadcast response to initial request via data subject', () => {
      autoPollingService.data.subscribe((result) => {
        expect(result).toEqual(new SearchResponse());
      });

      autoPollingService.start();
    });

    it('should start polling when start called', fakeAsync(() => {
      spyOn(searchServiceFake, 'search').and.callThrough();

      autoPollingService.start();

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);

      autoPollingService.stop();
    }));

    it('should broadcast polling response via data subject', fakeAsync(() => {
      const searchObservableFake = new Subject<SearchResponse>();
      const pollResponseFake = new SearchResponse();

      autoPollingService.start();
      // The reason am mocking the searchService.search here is to not interfere
      // with the initial request triggered right after the start
      searchServiceFake.search = () => searchObservableFake;

      autoPollingService.data.subscribe((result) => {
        expect(result).toBe(pollResponseFake);
        autoPollingService.stop();
      });

      tick(autoPollingService.getInterval() * 1000);

      searchObservableFake.next(pollResponseFake);
    }));

    it('should polling and broadcasting based on the interval', fakeAsync(() => {
      const searchObservableFake = new Subject<SearchResponse>();
      const broadcastObserverSpy = jasmine.createSpy('broadcastObserverSpy');
      const testInterval = 2;

      autoPollingService.setInterval(testInterval);
      autoPollingService.start();

      // The reason am mocking the searchService.search here is to not interfere
      // with the initial request triggered right after the start
      searchServiceFake.search = () => searchObservableFake;
      spyOn(searchServiceFake, 'search').and.callThrough();

      autoPollingService.data.subscribe(broadcastObserverSpy);

      tick(testInterval * 1000);
      expect(searchServiceFake.search).toHaveBeenCalledTimes(1);

      searchObservableFake.next({ total: 2 } as SearchResponse);
      expect(broadcastObserverSpy).toHaveBeenCalledTimes(1);
      expect(broadcastObserverSpy.calls.argsFor(0)[0]).toEqual({ total: 2 });

      tick(testInterval * 1000);
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);

      searchObservableFake.next({ total: 3 } as SearchResponse);
      expect(broadcastObserverSpy).toHaveBeenCalledTimes(2);
      expect(broadcastObserverSpy.calls.argsFor(1)[0]).toEqual({ total: 3 });

      autoPollingService.stop();
    }));

    it('interval change should impact the polling even when it is active', fakeAsync(() => {
      autoPollingService.start();

      // The reason am mocking the searchService.search here is to not interfere
      // with the initial request triggered right after the start
      spyOn(searchServiceFake, 'search').and.callThrough();

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(1);

      autoPollingService.setInterval(9);

      tick(4000);
      expect(searchServiceFake.search).toHaveBeenCalledTimes(1);

      tick(5000);
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);

      autoPollingService.setInterval(2);

      tick(1000);
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);

      tick(1000);
      expect(searchServiceFake.search).toHaveBeenCalledTimes(3);

      autoPollingService.stop();
    }));

    it('should stop polling when stop triggered', fakeAsync(() => {
      const searchObservableFake = new Subject<SearchResponse>();
      const broadcastObserverSpy = jasmine.createSpy('broadcastObserverSpy');

      autoPollingService.start();

      // The reason am mocking the searchService.search here is to not interfere
      // with the initial request triggered right after the start
      searchServiceFake.search = () => searchObservableFake;
      spyOn(searchServiceFake, 'search').and.callThrough();

      autoPollingService.data.subscribe(broadcastObserverSpy);

      tick(getIntervalInMS());
      searchObservableFake.next({ total: 3 } as SearchResponse);
      expect(searchServiceFake.search).toHaveBeenCalledTimes(1);

      autoPollingService.stop();

      tick(getIntervalInMS() * 4);
      expect(searchServiceFake.search).toHaveBeenCalledTimes(1);
    }));

    it('should use the latest query from query builder', fakeAsync(() => {
      const queryBuilderFake = TestBed.get(QueryBuilder);
      spyOn(searchServiceFake, 'search').and.callThrough();

      queryBuilderFake.setFilter('testFieldAA:testValueAA');
      autoPollingService.start();
      expect((searchServiceFake.search as Spy).calls.argsFor(0)[0].query).toBe('testFieldAA:testValueAA');

      queryBuilderFake.setFilter('testFieldBB:testValueBB');
      tick(getIntervalInMS());
      expect((searchServiceFake.search as Spy).calls.argsFor(1)[0].query).toBe('testFieldBB:testValueBB');

      queryBuilderFake.setFilter('*');
      tick(getIntervalInMS());
      expect((searchServiceFake.search as Spy).calls.argsFor(2)[0].query).toBe('*');

      autoPollingService.stop();
    }));

    it('should show notification on http error', fakeAsync(() => {
      const fakeDialogService = TestBed.get(DialogService);
      fakeDialogService.launchDialog = () => {};
      spyOn(fakeDialogService, 'launchDialog');

      autoPollingService.start();

      spyOn(searchServiceFake, 'search').and.returnValue(throwError(new RestError()));

      tick(getIntervalInMS());

      expect(fakeDialogService.launchDialog).toHaveBeenCalledWith(
        'Server were unable to apply query string. Evaluate query string and restart polling.',
        DialogType.Error
      );

      autoPollingService.stop();
    }));
  });

  describe('polling suppression - to prevent collision with other features', () => {
    it('should suspend polling even if it is started', fakeAsync(() => {
      spyOn(searchServiceFake, 'search').and.callThrough();

      autoPollingService.start();
      expect(searchServiceFake.search).toHaveBeenCalledTimes(1);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(3);

      autoPollingService.setSuppression(true);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(3);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(3);

      autoPollingService.stop();
    }));

    it('should continue polling when freed from suppression if it is started ', fakeAsync(() => {
      spyOn(searchServiceFake, 'search').and.callThrough();

      autoPollingService.start();
      expect(searchServiceFake.search).toHaveBeenCalledTimes(1);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(3);

      autoPollingService.setSuppression(true);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(3);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(3);

      autoPollingService.setSuppression(false);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(4);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(5);

      autoPollingService.stop();
    }));

    it('should have no impact when polling stopped', fakeAsync(() => {
      spyOn(searchServiceFake, 'search').and.callThrough();

      autoPollingService.start();
      expect(searchServiceFake.search).toHaveBeenCalledTimes(1);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);

      autoPollingService.stop();
      autoPollingService.setSuppression(true);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);

      autoPollingService.setSuppression(false);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);
    }));
  });

  describe('request congestion handling - when refresh interval faster than response time', () => {
    it('should skip new poll request when there is congestion', fakeAsync(() => {
      const searchObservableFake = new Subject<SearchResponse>();

      searchServiceFake.search = () => searchObservableFake;
      spyOn(searchServiceFake, 'search').and.callThrough();

      autoPollingService.start();

      searchObservableFake.next({ total: 2 } as SearchResponse);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);
      expect(autoPollingService.getIsCongestion()).toBe(false);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);
      expect(autoPollingService.getIsCongestion()).toBe(true);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);
      expect(autoPollingService.getIsCongestion()).toBe(true);

      autoPollingService.stop();
    }));

    it('should continue polling when congestion resolves', fakeAsync(() => {
      const searchObservableFake = new Subject<SearchResponse>();

      searchServiceFake.search = () => searchObservableFake;
      spyOn(searchServiceFake, 'search').and.callThrough();

      autoPollingService.start();

      searchObservableFake.next({ total: 2 } as SearchResponse);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);
      expect(autoPollingService.getIsCongestion()).toBe(false);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);
      expect(autoPollingService.getIsCongestion()).toBe(true);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);
      expect(autoPollingService.getIsCongestion()).toBe(true);

      searchObservableFake.next({ total: 2 } as SearchResponse);

      tick(getIntervalInMS());
      expect(searchServiceFake.search).toHaveBeenCalledTimes(3);
      expect(autoPollingService.getIsCongestion()).toBe(false);

      autoPollingService.stop();
    }));
  });

  describe('cancellation by manual request', () => {

    it('should be able to drop current response and continue polling', fakeAsync(() => {
      const broadcastObserverSpy = jasmine.createSpy('broadcastObserverSpy');
      const searchObservableFake = new Subject<SearchResponse>();

      autoPollingService.start();

      searchServiceFake.search = () => searchObservableFake;
      spyOn(searchServiceFake, 'search').and.callThrough();

      autoPollingService.data.subscribe(broadcastObserverSpy);

      tick(getIntervalInMS());

      expect(searchServiceFake.search).toHaveBeenCalledTimes(1);
      searchObservableFake.next({ total: 2 } as SearchResponse);
      expect(broadcastObserverSpy).toHaveBeenCalledTimes(1);

      tick(getIntervalInMS() / 2);
      autoPollingService.dropNextAndContinue();
      tick(getIntervalInMS() / 2);

      expect(searchServiceFake.search).toHaveBeenCalledTimes(1);
      searchObservableFake.next({ total: 3 } as SearchResponse);
      expect(broadcastObserverSpy).toHaveBeenCalledTimes(1);

      tick(getIntervalInMS());

      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);
      searchObservableFake.next({ total: 4 } as SearchResponse);
      expect(broadcastObserverSpy).toHaveBeenCalledTimes(2);

      autoPollingService.stop();
    }));

  });

  describe('polling state persisting and restoring', () => {

    it('should persist polling state on start', () => {
      spyOn(localStorage, 'setItem');
      autoPollingService.start();
      expect(localStorage.setItem).toHaveBeenCalledWith('autoPolling', `{"isActive":true,"refreshInterval":${DEFAULT_POLLING_INTERVAL}}`);
    });

    it('should persist polling state on stop', () => {
      spyOn(localStorage, 'setItem');
      autoPollingService.stop();
      expect(localStorage.setItem).toHaveBeenCalledWith('autoPolling', `{"isActive":false,"refreshInterval":${DEFAULT_POLLING_INTERVAL}}`);
    });

    it('should persist polling state on interval change', () => {
      spyOn(localStorage, 'setItem');
      autoPollingService.setInterval(4);
      expect(localStorage.setItem).toHaveBeenCalledWith('autoPolling', '{"isActive":false,"refreshInterval":4}');
    });

    it('should restore polling state on construction', () => {
      const queryBuilderFake = TestBed.get(QueryBuilder);
      const dialogServiceFake = TestBed.get(DialogService);

      spyOn(localStorage, 'getItem').and.returnValue('{"isActive":true,"refreshInterval":443}');

      const localAutoPollingSvc = new AutoPollingService(searchServiceFake, queryBuilderFake, dialogServiceFake);

      expect(localStorage.getItem).toHaveBeenCalledWith('autoPolling');
      expect(localAutoPollingSvc.getIsPollingActive()).toBe(true);
      expect(localAutoPollingSvc.getInterval()).toBe(443);
    });

    it('should start polling on construction when persisted isActive==true', fakeAsync(() => {
      const queryBuilderFake = TestBed.get(QueryBuilder);
      const dialogServiceFake = TestBed.get(DialogService);

      spyOn(searchServiceFake, 'search').and.callThrough();
      spyOn(localStorage, 'getItem').and.returnValue('{"isActive":true,"refreshInterval":10}');

      const localAutoPollingSvc = new AutoPollingService(searchServiceFake, queryBuilderFake, dialogServiceFake);

      expect(searchServiceFake.search).toHaveBeenCalledTimes(1);

      tick(localAutoPollingSvc.getInterval() * 1000);
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);

      tick(localAutoPollingSvc.getInterval() * 1000);
      expect(searchServiceFake.search).toHaveBeenCalledTimes(3);

      localAutoPollingSvc.stop();
    }));

    it('should start polling on construction with the persisted interval', fakeAsync(() => {
      const queryBuilderFake = TestBed.get(QueryBuilder);
      const dialogServiceFake = TestBed.get(DialogService);

      spyOn(searchServiceFake, 'search').and.callThrough();
      spyOn(localStorage, 'getItem').and.returnValue('{"isActive":true,"refreshInterval":4}');

      const localAutoPollingSvc = new AutoPollingService(searchServiceFake, queryBuilderFake, dialogServiceFake);

      expect(searchServiceFake.search).toHaveBeenCalledTimes(1);

      tick(4000);
      expect(searchServiceFake.search).toHaveBeenCalledTimes(2);

      tick(4000);
      expect(searchServiceFake.search).toHaveBeenCalledTimes(3);

      localAutoPollingSvc.stop();
    }));
  });

});
