
/*
 * Copyright 2017-present Open Networking Foundation

 * Licensed 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 * as angular from 'angular';
import 'angular-mocks';
import 'angular-resource';
import {IXosModelStoreService, XosModelStore} from './model.store';
import {Subject} from 'rxjs';
import {IWSEvent} from '../websocket/global';
import {StoreHelpers} from '../helpers/store.helpers';
import {ModelRest} from '../rest/model.rest';
import {ConfigHelpers} from '../../core/services/helpers/config.helpers';
import {AuthService} from '../rest/auth.rest';
import {XosDebouncer} from '../../core/services/helpers/debounce.helper';
import {IXosModeldefsCache} from '../helpers/modeldefs.service';

let service: IXosModelStoreService;
let httpBackend: ng.IHttpBackendService;
let $scope;
let WebSocket;
let XosModeldefsCache;

class MockWs {
  private _list;
  constructor() {
    this._list = new Subject<IWSEvent>();
  }
  list() {
    return this._list.asObservable();
  }

  next(event: IWSEvent) {
    this._list.next(event);
  }
}

const queryData = [
  {id: 1, name: 'foo'},
  {id: 2, name: 'bar'}
];

const MockAppCfg = {
  apiEndpoint: 'http://xos-test:3000/api',
  websocketClient: 'http://xos-test:3000'
};

describe('The ModelStore service', () => {

  beforeEach(() => {
    angular
      .module('ModelStore', ['ngResource', 'toastr', 'ngCookies'])
      .service('WebSocket', MockWs)
      .service('StoreHelpers', StoreHelpers) // TODO mock
      .service('ModelRest', ModelRest) // TODO mock
      .service('XosModelStore', XosModelStore)
      .service('ConfigHelpers', ConfigHelpers) // TODO mock
      .service('AuthService', AuthService)
      .constant('AppConfig', MockAppCfg)
      .value('XosModeldefsCache', {
        get: jasmine.createSpy('XosModeldefsCache.get').and.returnValue({}),
        getApiUrlFromModel: jasmine.createSpy('XosModeldefsCache.getApiUrlFromModel')
      })
      .service('XosDebouncer', XosDebouncer);

    angular.mock.module('ModelStore');
  });

  beforeEach(angular.mock.inject((
    XosModelStore: IXosModelStoreService,
    $httpBackend: ng.IHttpBackendService,
    _$rootScope_: ng.IRootScopeService,
    _WebSocket_: any,
    _XosModeldefsCache_: IXosModeldefsCache
  ) => {
    service = XosModelStore;
    httpBackend = $httpBackend;
    $scope = _$rootScope_;
    WebSocket = _WebSocket_;
    XosModeldefsCache = _XosModeldefsCache_;

    // ModelRest will call the backend
    httpBackend.whenGET(`${MockAppCfg.apiEndpoint}/core/samples`)
      .respond(queryData);
  }));

  describe('the QUERY method', () => {
    it('should return an Observable', () => {
      expect(typeof service.query('test').subscribe).toBe('function');
    });

    it('the first event should be the resource response', (done) => {
      XosModeldefsCache.getApiUrlFromModel.and.returnValue(`/core/samples`);
      let event = 0;
      service.query('sample')
        .subscribe(collection => {
          event++;
          if (event === 2) {
            expect(collection[0].id).toEqual(queryData[0].id);
            expect(collection[1].id).toEqual(queryData[1].id);
            done();
          }
        });
      $scope.$apply();
      httpBackend.flush();
    });
  });

  describe('the GET method', () => {
    it('should return an observable containing a single model', (done) => {
      let event = 0;
      XosModeldefsCache.getApiUrlFromModel.and.returnValue(`/core/samples`);
      service.get('sample', queryData[1].id)
        .subscribe((model) => {
          event++;
          if (event === 2) {
            expect(model.id).toEqual(queryData[1].id);
            expect(model.name).toEqual(queryData[1].name);
            done();
          }
        });
      httpBackend.flush();
      $scope.$apply();
    });
  });

  describe('when a web-socket event is received for that model', () => {
    it('should update the collection', (done) => {
      let event = 0;
      service.query('sample')
        .subscribe(
          collection => {
            event++;
            if (event === 3) {
              expect(collection[0].id).toEqual(queryData[0].id);
              expect(collection[1].id).toEqual(queryData[1].id);
              expect(collection[2].id).toEqual(3);
              expect(collection[2].name).toEqual('baz');
              done();
            }
          },
          err => {
            done(err);
          }
        );
      window.setTimeout(() => {
        WebSocket.next({
          model: 'sample',
          msg: {
            changed_fields: ['id'],
            object: {id: 3, name: 'baz'},
            pk: 3
          }
        });
      }, 1);
      $scope.$apply();
      httpBackend.flush();
    });
  });

  describe('when multiple stores are requested', () => {

    beforeEach(() => {
      httpBackend.expectGET(`${MockAppCfg.apiEndpoint}/core/firsts`)
        .respond([
          {first: 'foo'}
        ]);
      httpBackend.expectGET(`${MockAppCfg.apiEndpoint}/core/seconds`)
        .respond([
          {second: 'foo'}
        ]);
    });
    it('should create different Subject', (done) => {
      let fevent = 0;
      let sevent = 0;
      XosModeldefsCache.get.and.callFake(v => v);
      XosModeldefsCache.getApiUrlFromModel.and.callFake(v => `/core/${v}s`);
      service.query('first')
        .subscribe(first => {
          fevent++;
          if (fevent >= 2) {
            service.query('second')
              .subscribe(second => {
                sevent++;
                if (sevent === 2) {
                  expect(first).not.toEqual(second);
                  done();
                }
              });
          }
        });
      $scope.$apply();
      httpBackend.flush();
    });
  });
});
