import { Component, ViewChild, NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Logger } from 'app/shared/logger.service';
import { MockLogger } from 'testing/logger.service';
import { MockPrettyPrinter } from 'testing/pretty-printer.service';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';

import { CodeTabsComponent } from './code-tabs.component';
import { CodeTabsModule } from './code-tabs.module';
import { PrettyPrinter } from './pretty-printer.service';

describe('CodeTabsComponent', () => {
  let fixture: ComponentFixture<HostComponent>;
  let hostComponent: HostComponent;
  let codeTabsComponent: CodeTabsComponent;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [ HostComponent ],
      imports: [ CodeTabsModule, NoopAnimationsModule ],
      schemas: [ NO_ERRORS_SCHEMA ],
      providers: [
       { provide: Logger, useClass: MockLogger },
       { provide: PrettyPrinter, useClass: MockPrettyPrinter },
      ]
    });

    fixture = TestBed.createComponent(HostComponent);
    fixture.detectChanges();

    hostComponent = fixture.componentInstance;
    codeTabsComponent = hostComponent.codeTabsComponent;
  });

  it('should get correct tab info', () => {
    const tabs = codeTabsComponent.tabs;
    expect(tabs.length).toBe(2);

    // First code pane expectations
    expect(tabs[0].class).toBe('class-A');
    expect(tabs[0].language).toBe('language-A');
    expect(tabs[0].linenums).toBe('linenums-A');
    expect(tabs[0].path).toBe('path-A');
    expect(tabs[0].region).toBe('region-A');
    expect(tabs[0].header).toBe('header-A');
    expect(tabs[0].code.toString().trim()).toBe('Code example 1');

    // Second code pane expectations
    expect(tabs[1].class).toBe('class-B');
    expect(tabs[1].language).toBe('language-B');
    expect(tabs[1].linenums).withContext('Default linenums should have been used')
        .toBe('default-linenums');
    expect(tabs[1].path).toBe('path-B');
    expect(tabs[1].region).toBe('region-B');
    expect(tabs[1].header).toBe('header-B');
    expect(tabs[1].code.toString().trim()).toBe('Code example 2');
  });

  it('should create the right number of tabs with the right labels and classes', () => {
    const matTabs = fixture.nativeElement.querySelectorAll('.mat-tab-label');
    expect(matTabs.length).toBe(2);

    expect(matTabs[0].textContent.trim()).toBe('header-A');
    expect(matTabs[0].querySelector('.class-A')).toBeTruthy();

    expect(matTabs[1].textContent.trim()).toBe('header-B');
    expect(matTabs[1].querySelector('.class-B')).toBeTruthy();
  });

  it('should show the first tab with the right code', () => {
    const codeContent = fixture.nativeElement.querySelector('aio-code').textContent;
    expect(codeContent.indexOf('Code example 1') !== -1).toBeTruthy();
  });

  it('should clean-up the projected tabs content once captured', () => {
    expect(codeTabsComponent.content.nativeElement.innerHTML).toBe('');
  });
});

@Component({
  selector: 'aio-host-comp',
  template: `
    <code-tabs linenums="default-linenums">
      <code-pane class="class-A"
                 language="language-A"
                 linenums="linenums-A"
                 path="path-A"
                 region="region-A"
                 header="header-A">
        Code example 1
      </code-pane>
      <code-pane class="class-B"
                 language="language-B"
                 path="path-B"
                 region="region-B"
                 header="header-B">
        Code example 2
      </code-pane>
    </code-tabs>
  `
})
class HostComponent {
  @ViewChild(CodeTabsComponent, {static: true}) codeTabsComponent: CodeTabsComponent;
}
