/* eslint-disable no-unused-vars */
import {mount} from 'enzyme';
import React from 'react';

import {
  DEFAULT_DASHBOARDS_CONTEXT, DashboardsContext,
} from 'src/context/DashboardsContext';
import * as Hooks from 'src/hooks';

import {DashboardsFactory} from 'tests/__fixtures__/dashboards';

describe('src/hooks', () => {
  const HookWrapper = ({context, hook, hookArgs, output}) => {
    const Children = (props) => {
      output.result = hook(...hookArgs);
      return <span>It works!</span>;
    };

    return (
      <DashboardsContext.Provider value={context}>
        <Children />
      </DashboardsContext.Provider>
    );
  };

  let context = null;

  beforeEach(() => {
    context = {
      ...DEFAULT_DASHBOARDS_CONTEXT,
      dashboards: DashboardsFactory(),
    };
  });

  describe('useServices', () => {
    it('returns the the current dashboard services', () => {
      // Given
      const output = {};
      context = {
        ...context,
        currentDashboardId: context.dashboards[0].id,
      };

      // When
      const component = mount(
        <HookWrapper
          context={context}
          hook={Hooks.useServices}
          hookArgs={[]}
          output={output}
        />
      );

      // Then
      expect(output.result).toEqual(context.dashboards[0].services);
    });
  });

  describe('useService', () => {
    it('returns the the specified service instance', () => {
      // Given
      const output = {};

      // When
      const component = mount(
        <HookWrapper
          context={context}
          hook={Hooks.useService}
          hookArgs={['FakeService', 'fake_instance']}
          output={output}
        />
      );

      // Then
      expect(output.result).toEqual(context.dashboards[0].services[0]);
    });
  });

  describe('useSaveServiceCharacteristics', () => {
    it('returns the saveServiceCharacteristics callback', () => {
      // Given
      const output = {};

      // WHen
      const component = mount(
        <HookWrapper
          context={context}
          hook={Hooks.useSaveServiceCharacteristics}
          hookArgs={[]}
          output={output}
        />
      );

      // Then
      expect(output.result).toBe(context.saveServiceCharacteristics);
    });
  });

  describe('useSaveServiceLayout', () => {
    it('returns the saveServiceLayout callback', () => {
      // Given
      const output = {};

      // When
      const component = mount(
        <HookWrapper
          context={context}
          hook={Hooks.useSaveServiceLayout}
          hookArgs={[]}
          output={output}
        />
      );

      // Then
      expect(output.result).toBe(context.saveServiceLayout);
    });
  });

  describe('useNukeService', () => {
    it('returns the nukeService callback', () => {
      // Given
      const output = {};

      // When
      const component = mount(
        <HookWrapper
          context={context}
          hook={Hooks.useNukeService}
          hookArgs={[]}
          output={output}
        />
      );

      // Then
      expect(output.result).toBe(context.nukeService);
    });
  });

  describe('useAddService', () => {
    it('returns the addService callback', () => {
      // Given
      const output = {};

      // When
      const component = mount(
        <HookWrapper
          context={context}
          hook={Hooks.useAddService}
          hookArgs={[]}
          output={output}
        />
      );

      // Then
      expect(output.result).toBe(context.addService);
    });
  });

  describe('useServicesSavingState', () => {
    it('returns the service saving state', () => {
      // Given
      const output = {};

      // When
      const component = mount(
        <HookWrapper
          context={context}
          hook={Hooks.useServicesSavingState}
          hookArgs={[]}
          output={output}
        />
      );

      // Then
      expect(output.result).toEqual({
        lastSaveTimestamp: context.lastSaveTimestamp,
        lastSaveError: context.lastSaveError,
        isSaving: context.isSaving,
      });
    });
  });

  describe('useWebSocketState', () => {
    it('returns the websocket state', () => {
      // Given
      const output = {};

      // When
      const component = mount(
        <HookWrapper
          context={context}
          hook={Hooks.useWebSocketState}
          hookArgs={[]}
          output={output}
        />
      );

      // Then
      expect(output.result).toEqual({
        isWebSocketConnected: context.isWebSocketConnected,
      });
    });
  });

  describe('useDashboards', () => {
    it('returns the dashboards', () => {
      // Given
      const output = {};

      // When
      const component = mount(
        <HookWrapper
          context={context}
          hook={Hooks.useDashboards}
          hookArgs={[]}
          output={output}
        />
      );

      // Then
      expect(output.result).toEqual(context.dashboards);
    });
  });

  describe('useCurrentDashboardId', () => {
    it('returns the dashboards', () => {
      // Given
      const output = {};

      // When
      const component = mount(
        <HookWrapper
          context={context}
          hook={Hooks.useCurrentDashboardId}
          hookArgs={[]}
          output={output}
        />
      );

      // Then
      expect(output.result).toEqual(context.currentDashboardId);
    });
  });

  describe('useSetCurrentDashboardId', () => {
    it('returns the setCurrentDashboardId callback', () => {
      // Given
      const output = {};

      // When
      const component = mount(
        <HookWrapper
          context={context}
          hook={Hooks.useSetCurrentDashboardId}
          hookArgs={[]}
          output={output}
        />
      );

      // Then
      expect(output.result).toBe(context.setCurrentDashboardId);
    });
  });

  describe('useDashboardsHash', () => {
    it('returns the dashboards hash', () => {
      // Given
      const output = {};

      // When
      const component = mount(
        <HookWrapper
          context={context}
          hook={Hooks.useDashboardsHash}
          hookArgs={[]}
          output={output}
        />
      );

      // Then
      expect(output.result).toEqual(context.dashboardsHash);
    });
  });

  describe('useAddDashboard', () => {
    it('returns the addDashboard callback', () => {
      // Given
      const output = {};

      // When
      const component = mount(
        <HookWrapper
          context={context}
          hook={Hooks.useAddDashboard}
          hookArgs={[]}
          output={output}
        />
      );

      // Then
      expect(output.result).toBe(context.addDashboard);
    });
  });
});
