/*-
 * ============LICENSE_START=======================================================
 * ONAP CLAMP
 * ================================================================================
 * Copyright (C) 2019 AT&T Intellectual Property. All rights
 *                             reserved.
 * Modifications Copyright (C) 2022 Nordix 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.
 * ============LICENSE_END============================================
 * ===================================================================
 *
 */
import React from 'react';
import { shallow } from 'enzyme';
import LoopUI from './LoopUI';
import OnapConstants from './utils/OnapConstants';

import LoopCache from './api/LoopCache';
import LoopActionService from './api/LoopActionService';
import LoopService from './api/LoopService';

import { ThemeConsumer } from 'styled-components'
import { GlobalClampStyle } from './theme/globalStyle.js';
import { DefaultClampTheme } from './theme/globalStyle.js';

export const shallowWithTheme = (children, theme = DefaultClampTheme) => {
  ThemeConsumer._currentValue = theme
  return shallow(children)
}
describe('Verify LoopUI', () => {
  beforeEach(() => {
    fetch.resetMocks();
    fetch.mockImplementation(() => {
      return Promise.resolve({
        ok: true,
        status: 200,
        text: () => "testUser"

      });
    });
  })

  const loopCache = new LoopCache({
    "name": "LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca",
    "components": {
      "POLICY": {
        "componentState": {
          "stateName": "UNKNOWN",
          "description": "The policies defined have NOT yet been created on the policy engine"
        }
      },
      "DCAE": {
        "componentState": {
          "stateName": "BLUEPRINT_DEPLOYED",
          "description": "The DCAE blueprint has been found in the DCAE inventory but not yet instancianted for this loop"
        }
      }
    }
  });

  it('Test the render method', async () => {
    const flushPromises = () => new Promise(setImmediate);

    const component = shallow(<LoopUI/>)
    component.setState({
      loopName: "testLoopName",
      showSucAlert: false,
      showFailAlert: false
    });
    await flushPromises();
    expect(component).toMatchSnapshot();
  });

  test('Test closeLoop method', () => {
    const historyMock = { push: jest.fn() };
    const component = shallow(<LoopUI history={ historyMock }/>)
    const instance = component.instance();
    instance.closeLoop();

    expect(component.state('loopName')).toEqual(OnapConstants.defaultLoopName);
    expect(historyMock.push.mock.calls[0]).toEqual(['/']);
  })

  test('Test loadLoop method refresh suc', async () => {
    const historyMock = { push: jest.fn() };
    LoopService.getLoop = jest.fn().mockImplementation(() => {
      return Promise.resolve({
        ok: true,
        status: 200,
        text: () => {
        }
      });
    });

    LoopActionService.refreshStatus = jest.fn().mockImplementation(() => {
      return Promise.resolve({ name: "LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca" });
    });

    const flushPromises = () => new Promise(setImmediate);
    const component = shallow(<LoopUI history={ historyMock }/>)
    const instance = component.instance();
    instance.loadLoop("LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca");

    await flushPromises();

    const resLoopCache = instance.getLoopCache();

    expect(resLoopCache.getComponentStates()).toBeUndefined();
    expect(component.state('loopName')).toEqual("LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca");
  })

  test('Test loadLoop method refresh fail', async () => {
    const historyMock = { push: jest.fn() };
    LoopService.getLoop = jest.fn().mockImplementation(() => {
      return Promise.resolve({
        name: "LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca",
        "components": {
          "POLICY": {
            "componentState": {
              "stateName": "UNKNOWN",
              "description": "The policies defined have NOT yet been created on the policy engine"
            }
          },
          "DCAE": {
            "componentState": {
              "stateName": "BLUEPRINT_DEPLOYED",
              "description": "The DCAE blueprint has been found in the DCAE inventory but not yet instancianted for this loop"
            }
          }
        }
      });
    });

    LoopActionService.refreshStatus = jest.fn().mockImplementation(() => {
      return Promise.reject({ error: "whatever" });
    });

    const flushPromises = () => new Promise(setImmediate);
    const component = shallow(<LoopUI history={ historyMock }/>)
    const instance = component.instance();
    instance.loadLoop("LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca");

    await flushPromises();

    const resLoopCache = instance.getLoopCache();

    expect(resLoopCache).toEqual(loopCache);
    expect(component.state('loopName')).toEqual("LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca");
  })

  test('Test alert methods', () => {
    const component = shallow(<LoopUI/>)
    expect(component.state('showSucAlert')).toEqual(false);

    const instance = component.instance();
    instance.showSucAlert("testAlert");
    expect(component.state('showSucAlert')).toEqual(true);
    expect(component.state('showFailAlert')).toEqual(false);
    expect(component.state('showMessage')).toEqual("testAlert");

    instance.disableAlert();

    expect(component.state('showSucAlert')).toEqual(false);
    expect(component.state('showFailAlert')).toEqual(false);

    instance.showFailAlert("testAlert2");
    expect(component.state('showSucAlert')).toEqual(false);
    expect(component.state('showFailAlert')).toEqual(true);
    expect(component.state('showMessage')).toEqual("testAlert2");
  })

  test('Test renders correctly Clamp Style', () => {
    let tree = shallowWithTheme(<GlobalClampStyle />);
    expect(tree).toMatchSnapshot();
  })
});
