// Copyright Project Harbor Authors
//
// 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.
import {
    ComponentFixture,
    TestBed,
    ComponentFixtureAutoDetect,
} from '@angular/core/testing';
import { VulnerabilityConfigComponent } from './vulnerability-config.component';
import { ScanAllRepoService } from './scanAll.service';
import { of } from 'rxjs';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ScanningMetrics, Triggers } from '../../config/config';
import { Scanner } from '../scanner/scanner';
import { SharedTestingModule } from '../../../../shared/shared.module';
import { delay } from 'rxjs/operators';
import { ScanAllService } from '../../../../../../ng-swagger-gen/services/scan-all.service';

let component: VulnerabilityConfigComponent;
let fixture: ComponentFixture<VulnerabilityConfigComponent>;
let mockedSchedule = { schedule: null };
let mockedScheduledMetrics: ScanningMetrics = {
    total: 50,
    completed: 50,
    metrics: {
        Success: 20,
        Error: 30,
    },
    ongoing: false,
    trigger: Triggers.SCHEDULE,
};
const mockedScanner: Scanner = {
    uuid: 'ca3c27f3-72f3-11ea-9e46-0242ac170004',
    name: 'trivy',
    description: '',
    url: 'http://10.92.161.247:8080',
    disabled: false,
    is_default: true,
    auth: '',
    skip_certVerify: false,
    use_internal_addr: true,
    create_time: '2020-03-31T02:03:18.379132Z',
    update_time: '2020-03-31T02:03:18.379135Z',
};
let fakedScanAllRepoService = {
    getSchedule() {
        return of(mockedSchedule);
    },
    getMetrics() {
        return of(mockedScheduledMetrics);
    },
    manualScan() {
        return of(true);
    },
    getScanners() {
        return of([mockedScanner]);
    },
    getScannerMetadata() {
        return of(null);
    },
};

const fakedScanAllService = {
    stopScanAll() {
        return of(null);
    },
};

describe('VulnerabilityConfigComponent', () => {
    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [SharedTestingModule],
            schemas: [CUSTOM_ELEMENTS_SCHEMA],
            declarations: [VulnerabilityConfigComponent],
            providers: [
                {
                    provide: ScanAllRepoService,
                    useValue: fakedScanAllRepoService,
                },
                { provide: ScanAllService, useValue: fakedScanAllService },
                // open auto detect
                { provide: ComponentFixtureAutoDetect, useValue: true },
            ],
        }).compileComponents();
    });

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

    it('should create', () => {
        expect(component).toBeTruthy();
        const ele = fixture.nativeElement.querySelector('.finished');
        expect(ele.style.width).toEqual('80px');
    });
    it('should loop metrics if  scheduled scanning is on going', () => {
        component.scanningMetrics.ongoing = true;
        expect(component.scanAvailable).toBeFalsy();
    });
    it('will trigger scan now and get manual metrics', () => {
        const button = fixture.nativeElement.querySelector('#scan');
        button.click();
        const ele = fixture.nativeElement.querySelector('.finished');
        expect(ele.style.width).toEqual('80px');
    });
    it('should stop looping  manual metrics if manual scanning is finished', () => {
        component.scanningMetrics.trigger = Triggers.MANUAL;
        component.scanningMetrics.ongoing = false;
        component.hasDefaultScanner = true;
        expect(component.scanAvailable).toBeTruthy();
        const spnManual: HTMLSpanElement =
            fixture.nativeElement.querySelector('.float-left');
        expect(spnManual.innerText).toEqual('CONFIG.SCANNING.SCHEDULED');
        const scanBtn: HTMLButtonElement =
            fixture.nativeElement.querySelector('#scan');
        scanBtn.click();
        const spnSchedule: HTMLSpanElement =
            fixture.nativeElement.querySelector('.float-left');
        expect(spnSchedule.innerText).toEqual('CONFIG.SCANNING.MANUAL');
    });
});
