import * as HomeHubCore from '@bthlabs/homehub-core';

import * as TradfriService from 'src/TradfriService';

import {TradfriDataFactory} from 'tests/__fixtures__/tradfri';

describe('src/TradfriService', () => {
  describe('TradfriService', () => {
    let fakeCharacteristics = null;
    let fakeResult = null;

    beforeEach(() => {
      fakeCharacteristics = {
        host: 'thisisntright.local',
        key: 'thisisntright',
      };
      fakeResult = TradfriDataFactory();

      spyOn(HomeHubCore.API.Services, 'start').and.returnValue(fakeResult);
      spyOn(HomeHubCore.API.Services, 'stop').and.returnValue('ok');
      spyOn(HomeHubCore.API.Services, 'use').and.returnValue(
        fakeResult.lights
      );
    });

    describe('emptyCharacteristics', () => {
      it('returns empty characteristics', () => {
        // Given
        const result = TradfriService.TradfriService.emptyCharacteristics();

        // Then
        expect(result).toEqual({
          key: '',
          host: '',
        });
      });
    });

    describe('start', () => {
      it('notifies subscribers with the result of start service API call', async () => {
        // Given
        const service = new TradfriService.TradfriService({
          instance: 'testing',
          characteristics: fakeCharacteristics,
        });
        spyOn(service, 'notify');

        // When
        await service.start();

        // Then
        expect(HomeHubCore.API.Services.start).toHaveBeenCalledWith(
          service.kind, 'testing', fakeCharacteristics
        );
        expect(service.notify).toHaveBeenCalledWith(fakeResult);
      });
    });

    describe('stop', () => {
      it('calls the stop service API method', async () => {
        // Given
        const service = new TradfriService.TradfriService({
          instance: 'testing',
          characteristics: fakeCharacteristics,
        });

        // When
        await service.stop();

        // Then
        expect(HomeHubCore.API.Services.stop).toHaveBeenCalledWith(
          service.kind, 'testing'
        );
      });
    });

    describe('setCharacteristics', () => {
      it('updates the service characteristics', () => {
        // Given
        const newCharacteristics = {
          host: 'thisisntrighttoo.local',
          key: 'thisisntrighttoo',
        };
        const service = new TradfriService.TradfriService({
          instance: 'testing',
          characteristics: fakeCharacteristics,
        });
        spyOn(service, 'restart');

        // When
        service.setCharacteristics(newCharacteristics);

        // Then
        expect(service.characteristics).toEqual(newCharacteristics);
      });

      it('restarts the service if host characteristic changed', () => {
        // Given
        const newCharacteristics = {
          ...fakeCharacteristics,
          host: 'thisisntrighttoo.local',
        };
        const service = new TradfriService.TradfriService({
          instance: 'testing',
          characteristics: fakeCharacteristics,
        });
        spyOn(service, 'restart');

        // When
        service.setCharacteristics(newCharacteristics);

        // Then
        expect(service.restart).toHaveBeenCalled();
      });

      it('restarts the service if key characteristic changed', () => {
        // Given
        const newCharacteristics = {
          ...fakeCharacteristics,
          key: 'thisisntrighttoo',
        };
        const service = new TradfriService.TradfriService({
          instance: 'testing',
          characteristics: fakeCharacteristics,
        });
        spyOn(service, 'restart');

        // When
        service.setCharacteristics(newCharacteristics);

        // Then
        expect(service.restart).toHaveBeenCalled();
      });
    });

    describe('setLightsState', () => {
      it('calls the use service capability API method', async () => {
        // Given
        const service = new TradfriService.TradfriService({
          instance: 'testing',
          characteristics: fakeCharacteristics,
        });

        // When
        const result = await service.setLightsState(['light1'], true);

        // Then
        expect(result).toEqual(fakeResult.lights);
        expect(HomeHubCore.API.Services.use).toHaveBeenCalledWith(
          service.kind, 'testing', 'set_lights_state', [['light1'], true],
        );
      });
    });
  });
});
