/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */

import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, DoCheck, OnChanges, OnInit} from '@angular/core';
import {Component, Directive} from '@angular/core/src/metadata';
import {TestBed, inject} from '@angular/core/testing';
import {Log} from '@angular/core/testing/src/testing_internal';

export function main() {
  describe('directive lifecycle integration spec', () => {
    let log: Log;

    beforeEach(() => {
      TestBed
          .configureTestingModule({
            declarations: [
              LifecycleCmp,
              LifecycleDir,
              MyComp5,
            ],
            providers: [Log]
          })
          .overrideComponent(MyComp5, {set: {template: '<div [field]="123" lifecycle></div>'}});
    });

    beforeEach(inject([Log], (_log: any) => { log = _log; }));

    it('should invoke lifecycle methods ngOnChanges > ngOnInit > ngDoCheck > ngAfterContentChecked',
       () => {
         const fixture = TestBed.createComponent(MyComp5);
         fixture.detectChanges();

         expect(log.result())
             .toEqual(
                 'ngOnChanges; ngOnInit; ngDoCheck; ngAfterContentInit; ngAfterContentChecked; child_ngDoCheck; ' +
                 'ngAfterViewInit; ngAfterViewChecked');

         log.clear();
         fixture.detectChanges();

         expect(log.result())
             .toEqual('ngDoCheck; ngAfterContentChecked; child_ngDoCheck; ngAfterViewChecked');
       });
  });
}


@Directive({selector: '[lifecycle-dir]'})
class LifecycleDir implements DoCheck {
  constructor(private _log: Log) {}
  ngDoCheck() { this._log.add('child_ngDoCheck'); }
}

@Component({
  selector: '[lifecycle]',
  inputs: ['field'],
  template: `<div lifecycle-dir></div>`,
})
class LifecycleCmp implements OnChanges,
    OnInit, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked {
  field: any /** TODO #9100 */;
  constructor(private _log: Log) {}

  ngOnChanges(_: any /** TODO #9100 */) { this._log.add('ngOnChanges'); }

  ngOnInit() { this._log.add('ngOnInit'); }

  ngDoCheck() { this._log.add('ngDoCheck'); }

  ngAfterContentInit() { this._log.add('ngAfterContentInit'); }

  ngAfterContentChecked() { this._log.add('ngAfterContentChecked'); }

  ngAfterViewInit() { this._log.add('ngAfterViewInit'); }

  ngAfterViewChecked() { this._log.add('ngAfterViewChecked'); }
}

@Component({selector: 'my-comp'})
class MyComp5 {
}
