import { Router } from '@angular/router';
import { ModeValidator } from './../../custom_modules/helpers/mode-validator';
/*
******************************************************************************
* Copyright © 2018 PTA GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
*
*     http://www.eclipse.org/legal/epl-v10.html
******************************************************************************
 */

import { async, fakeAsync, tick, ComponentFixture, TestBed } from '@angular/core/testing';

import { SingleGridMeasureDetailTabComponent } from './single-grid-measure-detail-tab.component';
import { StringToDatePipe } from '../../common-components/pipes/string-to-date.pipe';
import { MockComponent } from '../../testing/mock.component';
import { FormsModule } from '@angular/forms';
import { SimpleChange } from '@angular/core';
import { SessionContext } from './../../common/session-context';
import { CimCacheService } from './../../services/cim-cache.service';
import { AbstractMockObservableService } from '../../testing/abstract-mock-observable.service';
import { GRIDMEASURE } from '../../test-data/grid-measures';
import { RESSOURCETYPESRESPONSE, RESSOURCEWITHTYPERESPONSE, RESSOURCEWITHTYPERESPONSE_2 } from '../../test-data/cim-cache-responses';
import { GridMeasureService } from '../../services/grid-measure.service';
import { RoleAccessHelperService } from '../../services/jobs/role-access-helper.service';
import { Util } from '../../common/util';
import { ToasterMessageService } from '../../services/toaster-message.service';
import { MessageService } from 'primeng/api';


describe('SingleGridMeasureDetailTabComponent', () => {
  let component: SingleGridMeasureDetailTabComponent;
  let fixture: ComponentFixture<SingleGridMeasureDetailTabComponent>;

  class MockCimCacheService extends AbstractMockObservableService {
    getRessourceTypes() {
      return this;
    }

    getRessourcesWithType() {
      return this;
    }
  }

  class MockGridmeasureService extends AbstractMockObservableService {
    storeGridMeasure() {
      return this;
    }
    getGridMeasure(id: number) {
      return this;
    }
  }

  let mockCimCacheService;
  let sessionContext: SessionContext;
  let mockGridmeasureService;
  let roleAccessHelper;
  let toasterMessageService: ToasterMessageService;
  let messageService: MessageService;

  beforeEach(async(() => {
    mockCimCacheService = new MockCimCacheService();
    sessionContext = new SessionContext();
    mockGridmeasureService = new MockGridmeasureService();
    roleAccessHelper = new RoleAccessHelperService();
    messageService = new MessageService;
    toasterMessageService = new ToasterMessageService(sessionContext, messageService);

    TestBed.configureTestingModule({
      imports: [
        FormsModule
      ],
      declarations: [
        SingleGridMeasureDetailTabComponent,
        StringToDatePipe,
        MockComponent({ selector: 'input', inputs: ['options'] }),
        MockComponent({
          selector: 'app-step',
          inputs: ['isReadOnlyForm', 'singleGridMeasure', 'gridMeasureDetail']
        }),
        MockComponent({
          selector: 'app-steps',
          inputs: ['gridId', 'withEditButtons', 'singleGridMeasure', 'gridMeasureDetail']
        })
      ],
      providers: [
        ModeValidator,
        { provide: Router },
        { provide: CimCacheService, useValue: mockCimCacheService },
        { provide: SessionContext, useClass: SessionContext },
        { provide: GridMeasureService, useValue: mockGridmeasureService },
        { provide: RoleAccessHelperService, useValue: roleAccessHelper },
        { provide: ToasterMessageService, useValue: toasterMessageService }
      ]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(SingleGridMeasureDetailTabComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  xit('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should set form in readonly mode', () => {
    component.readOnlyForm = false;
    fixture.detectChanges();
    component.ngOnChanges({
      isReadOnlyForm: new SimpleChange(component.readOnlyForm, true, true)
    });
    fixture.detectChanges();
    expect(component.readOnlyForm).toBeTruthy();
  });

  it('should have one singlegridmeasure', () => {
    component.gridMeasureDetail = JSON.parse(JSON.stringify(GRIDMEASURE[0]));
    expect(component.gridMeasureDetail.listSingleGridmeasures.length).toBe(2);
    const gridMeasure = component.gridMeasureDetail;
    gridMeasure.listSingleGridmeasures.pop();

    fixture.detectChanges();
    component.ngOnChanges({
      gridMeasureDetail: new SimpleChange(component.gridMeasureDetail, gridMeasure, true)
    });
    fixture.detectChanges();
    expect(component.gridMeasureDetail.listSingleGridmeasures.length).toBe(1);

    gridMeasure.listSingleGridmeasures.pop();
    fixture.detectChanges();
    component.ngOnChanges({
      gridMeasureDetail: new SimpleChange(component.gridMeasureDetail, gridMeasure, true)
    });
    fixture.detectChanges();
    expect(component.gridMeasureDetail.listSingleGridmeasures.length).toBe(1);

  });

  it('should handle cim-service error on init', fakeAsync(() => {
    spyOn(console, 'log').and.callThrough();
    component.gridMeasureDetail = JSON.parse(JSON.stringify(GRIDMEASURE[0]));
    mockCimCacheService.error = 'CimCache error';
    mockCimCacheService.content = [];

    component.ngOnInit();
    tick();

    fixture.detectChanges();
    expect(console.log).toHaveBeenCalled();
  }));

  it('should handle cim-service error on onChangeResourceGroup', fakeAsync(() => {
    spyOn(console, 'log').and.callThrough();
    component.gridMeasureDetail = JSON.parse(JSON.stringify(GRIDMEASURE[0]));
    mockCimCacheService.error = 'CimCache error';
    mockCimCacheService.content = [];

    component.onChangeResourceGroup('fake');
    tick();

    fixture.detectChanges();
    expect(console.log).toHaveBeenCalled();
  }));

  it('should call getRessourceTypes on init', fakeAsync(() => {

    spyOn((component as any), 'getRessourceTypes').and.callThrough();
    spyOn((component as any), 'processRessourceTypesResponse').and.callThrough();
    spyOn((component as any), 'getRessourceTypesWithType').and.callThrough();
    (component as any).cimCacheService.content = RESSOURCETYPESRESPONSE;
    component.gridMeasureDetail = JSON.parse(JSON.stringify(GRIDMEASURE[0]));

    component.ngOnInit();
    tick();

    fixture.detectChanges();
    expect((component as any).getRessourceTypes).toHaveBeenCalled();

    fixture.whenStable().then(() => {
      fixture.detectChanges();
      expect((component as any).processRessourceTypesResponse).toHaveBeenCalled();

      component.onChangeResourceGroup(null);
      fixture.detectChanges();
      expect(component.singleGMAffectedResourcesList.length).toBe(0);

      component.onChangeResourceGroup('ac-line-segment');
      fixture.detectChanges();
      expect((component as any).getRessourceTypesWithType).toHaveBeenCalled();
    });
  }));

  it('should convert xmlstring to json correctly', () => {
    const xmlstring = `<root>
    <child><textNode>First &amp; Child</textNode></child>
    <child><textNode>Second Child</textNode></child>
    <testAttrs attr1='attr1Value'/>
    </root>`;
    const jsonstring = `{"root":{"child":[{"textNode":"First & Child"},{"textNode":"Second Child"}],"testAttrs":{"_attr1":"attr1Value"}}}`;
    expect(JSON.stringify(component.convertXmlToJsonObj(xmlstring))).toBe(jsonstring);
  });

  it('should processRessourceWithTypeResponse correctly', () => {
    const res_input = RESSOURCEWITHTYPERESPONSE;

    component.singleGridMeasure.powerSystemResource = null;
    component.processRessourceWithTypeResponse(res_input);
    fixture.detectChanges();
    expect(component.singleGridMeasure.powerSystemResource.cimName).toContain(' - PowerTransformer');
  });

  it('should processRessourceWithTypeResponse with array type correctly', () => {
    const res_input = RESSOURCEWITHTYPERESPONSE_2;

    component.singleGMAffectedResourcesList = [];
    component.processRessourceWithTypeResponse(res_input);
    fixture.detectChanges();
    expect(component.singleGMAffectedResourcesList.length).toBe(2);
  });

  it('should processRessourceTypesResponse correctly', () => {
    const res_input = RESSOURCETYPESRESPONSE;
    component.singleGMAffectedResourcesGroupList = [];
    component.processRessourceTypesResponse(res_input);
    fixture.detectChanges();
    expect(component.singleGMAffectedResourcesGroupList.length).toBe(21);
  });

  // it('should init InactiveFields correctly with readonly form=false', () => {
  //   const el: HTMLElement = component.singleGridMeasureDetailFormContainer.nativeElement as HTMLElement;
  //   component.readOnlyForm = false;
  //   const fields: NodeListOf<Element> = el.querySelectorAll('#singleGMAffectedResourcesGroupList');
  //   const htmlElem: HTMLInputElement = fields.item(0) as HTMLInputElement;
  //   htmlElem.disabled = true;
  //   component.initInactiveFields();
  //   expect((fields.item(0) as HTMLInputElement).disabled).toBe(false);
  // });

  // it('should init InactiveFields correctly with readonly form=true', () => {
  //   const el: HTMLElement = component.singleGridMeasureDetailFormContainer.nativeElement as HTMLElement;
  //   component.readOnlyForm = true;
  //   const fields: NodeListOf<Element> = el.querySelectorAll('#singleGMAffectedResourcesGroupList');
  //   const htmlElem: HTMLInputElement = fields.item(0) as HTMLInputElement;
  //   htmlElem.disabled = false;
  //   component.initInactiveFields();
  //   expect((fields.item(0) as HTMLInputElement).disabled).toBe(true);
  // });

  it('should work with duplicateSingleGM correctly', () => {
    component.gridMeasureDetail = JSON.parse(JSON.stringify(GRIDMEASURE[0]));
    component.singleGridMeasure = JSON.parse(JSON.stringify(GRIDMEASURE[0].listSingleGridmeasures[0]));

    const lengthBefore = component.gridMeasureDetail.listSingleGridmeasures.length;
    const compList = component.gridMeasureDetail.listSingleGridmeasures[0].listSteps;

    component.duplicateSingleGM();

    expect(component.gridMeasureDetail.listSingleGridmeasures.length).toBe(lengthBefore + 1);
    expect(compList[0].switchingObject).toBe(
      component.gridMeasureDetail.listSingleGridmeasures[lengthBefore].listSteps[compList.length - 1].switchingObject);
  });

  it('should emit decision message after click on delete', () => {
    spyOn((component as any).toasterMessageService, 'showSingleGMDeleteConfirm');

    component.onDeleteBtnClick();
    fixture.detectChanges();
    fixture.whenStable().then(() => {
      expect((component as any).toasterMessageService.showSingleGMDeleteConfirm).toHaveBeenCalled();
    });
  });

  it('should process delete and emit info message', () => {
    spyOn((component as any).toasterMessageService, 'showSuccess');
    spyOn(component, 'getPreviousSingleGridmeasure').and.callThrough();
    spyOn(Util, 'showGridmeasureTab');
    component.gridMeasureDetail = JSON.parse(JSON.stringify(GRIDMEASURE[0]));
    component.singleGridMeasure = JSON.parse(JSON.stringify(GRIDMEASURE[0].listSingleGridmeasures[1]));

    expect(component.singleGridMeasure.id).toBe(5);
    (component as any).processDeleteSingleGridMeasure();
    fixture.detectChanges();
    fixture.whenStable().then(() => {
      expect((component as any).toasterMessageService.showSuccess).toHaveBeenCalled();
      expect(component.getPreviousSingleGridmeasure).toHaveBeenCalled();
      expect(component.singleGridMeasure.id).toBe(3);
    });

    (component as any).processDeleteSingleGridMeasure();
    fixture.detectChanges();
    fixture.whenStable().then(() => {
      expect((component as any).messageService.emitInfo).toHaveBeenCalled();
      expect(component.getPreviousSingleGridmeasure).toHaveBeenCalled();
      expect(Util.showGridmeasureTab).toHaveBeenCalled();
    });
  });

});
