import { Component, OnInit, Input } from '@angular/core';
import {
    ScanningResultService,
    VulnerabilityItem
} from '../service/index';
import { ErrorHandler } from '../error-handler/index';
import { forkJoin } from "rxjs";

import { ChannelService } from "../channel/channel.service";
import { UserPermissionService } from "../service/permission.service";
import { USERSTATICPERMISSION } from "../service/permission-static";
import { DEFAULT_SUPPORTED_MIME_TYPE, VULNERABILITY_SEVERITY } from '../utils';
import { finalize } from "rxjs/operators";


@Component({
    selector: 'hbr-vulnerabilities-grid',
    templateUrl: './result-grid.component.html',
    styleUrls: ['./scanning.scss']
})
export class ResultGridComponent implements OnInit {
    scanningResults: VulnerabilityItem[] = [];
    dataCache: VulnerabilityItem[] = [];
    loading: boolean = false;
    @Input() tagId: string;
    @Input() repositoryId: string;
    @Input() projectId: number;
    hasScanImagePermission: boolean;
    constructor(
        private scanningService: ScanningResultService,
        private channel: ChannelService,
        private userPermissionService: UserPermissionService,
        private errorHandler: ErrorHandler,
    ) { }

    ngOnInit(): void {
        this.loadResults(this.repositoryId, this.tagId);
        this.getScanPermissions(this.projectId);
        this.channel.tagDetail$.subscribe(tag => {
            this.loadResults(this.repositoryId, this.tagId);
        });

    }

    loadResults(repositoryId: string, tagId: string): void {
        this.loading = true;
        this.scanningService.getVulnerabilityScanningResults(repositoryId, tagId)
            .pipe(finalize(() => this.loading = false))
            .subscribe((results) => {
                if (results && results[DEFAULT_SUPPORTED_MIME_TYPE]) {
                    let report = results[DEFAULT_SUPPORTED_MIME_TYPE];
                    if (report.vulnerabilities) {
                        this.dataCache = report.vulnerabilities;
                        this.scanningResults = this.dataCache.filter((item: VulnerabilityItem) => item.id !== '');
                        return;
                    }
                }
            }, error => { this.errorHandler.error(error); });
    }

    // TODO: Should query from back-end service
    filterVulnerabilities(terms: string): void {
        if (terms.trim() === '') {
            this.scanningResults = this.dataCache.filter((item: VulnerabilityItem) => item.id !== '');
        } else {
            this.scanningResults = this.dataCache.filter((item: VulnerabilityItem) => this._regexpFilter(terms, item.package));
        }
    }

    refresh(): void {
        this.loadResults(this.repositoryId, this.tagId);
    }

    severityText(severity: string): string {
        switch (severity) {
            case VULNERABILITY_SEVERITY.CRITICAL:
                return 'VULNERABILITY.SEVERITY.CRITICAL';
            case VULNERABILITY_SEVERITY.HIGH:
                return 'VULNERABILITY.SEVERITY.HIGH';
            case VULNERABILITY_SEVERITY.MEDIUM:
                return 'VULNERABILITY.SEVERITY.MEDIUM';
            case VULNERABILITY_SEVERITY.LOW:
                return 'VULNERABILITY.SEVERITY.LOW';
            case VULNERABILITY_SEVERITY.NEGLIGIBLE:
                return 'VULNERABILITY.SEVERITY.NEGLIGIBLE';
            case VULNERABILITY_SEVERITY.UNKNOWN:
                return 'VULNERABILITY.SEVERITY.UNKNOWN';
            default:
                return 'UNKNOWN';
        }
    }

    _regexpFilter(terms: string, testedValue: any): boolean {
        let reg = new RegExp('.*' + terms + '.*', 'i');
        return reg.test(testedValue);
    }

    scanNow(): void {
        this.channel.publishScanEvent(this.repositoryId + "/" + this.tagId);
    }
    getScanPermissions(projectId: number): void {

        const hasScanImagePermission = this.userPermissionService.getPermission(projectId,
            USERSTATICPERMISSION.REPOSITORY_TAG_SCAN_JOB.KEY, USERSTATICPERMISSION.REPOSITORY_TAG_SCAN_JOB.VALUE.CREATE);
        forkJoin(hasScanImagePermission).subscribe(permissions => {
            this.hasScanImagePermission = permissions[0] as boolean;
        }, error => {
            this.errorHandler.error(error);
        });
    }
}
