// 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 { Component, Input, OnInit } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import {
    ScannerVo,
    VulnerabilitySummary,
} from '../../../../../../shared/services';
import {
    VULNERABILITY_SCAN_STATUS,
    VULNERABILITY_SEVERITY,
} from '../../../../../../shared/units/utils';
import { HAS_STYLE_MODE, StyleMode } from '../../../../../../services/theme';
import { SeverityColors } from '../../../../../left-side-nav/interrogation-services/vulnerability-database/security-hub.interface';

const MIN = 60;
const MIN_STR = 'min ';
const SEC_STR = 'sec';
const SUCCESS_PCT: number = 100;
const CLASS_MAP = {
    CRITICAL: 'level-critical',
    HIGH: 'level-high',
    MEDIUM: 'level-medium',
    LOW: 'level-low',
    NONE: 'level-none',
};

@Component({
    selector: 'hbr-result-tip-histogram',
    templateUrl: './result-tip-histogram.component.html',
    styleUrls: ['./result-tip-histogram.component.scss'],
})
export class ResultTipHistogramComponent implements OnInit {
    @Input() scanner: ScannerVo;
    _tipTitle: string = '';
    @Input() vulnerabilitySummary: VulnerabilitySummary = {
        scan_status: VULNERABILITY_SCAN_STATUS.NOT_SCANNED,
        severity: '',
    };
    constructor(private translate: TranslateService) {}

    ngOnInit(): void {
        let key = 'VULNERABILITY.SEVERITY.NONE';
        switch (this.vulnerabilitySummary.severity) {
            case VULNERABILITY_SEVERITY.CRITICAL:
                key = 'VULNERABILITY.SEVERITY.CRITICAL';
                break;
            case VULNERABILITY_SEVERITY.HIGH:
                key = 'VULNERABILITY.SEVERITY.HIGH';
                break;
            case VULNERABILITY_SEVERITY.MEDIUM:
                key = 'VULNERABILITY.SEVERITY.MEDIUM';
                break;
            case VULNERABILITY_SEVERITY.LOW:
                key = 'VULNERABILITY.SEVERITY.LOW';
                break;
            default:
                break;
        }

        this.translate.get(key).subscribe((res: string) => {
            this._tipTitle = res;
        });
    }

    get tipTitle(): string {
        return this._tipTitle;
    }

    get total(): number {
        if (
            this.vulnerabilitySummary &&
            this.vulnerabilitySummary.summary &&
            this.vulnerabilitySummary.summary.total
        ) {
            return this.vulnerabilitySummary.summary.total;
        }
        return 0;
    }
    get fixableCount() {
        if (
            this.vulnerabilitySummary &&
            this.vulnerabilitySummary.summary &&
            this.vulnerabilitySummary.summary.fixable
        ) {
            return this.vulnerabilitySummary.summary.fixable;
        }
        return 0;
    }

    get sevSummary(): { [key: string]: number } {
        if (this.vulnerabilitySummary && this.vulnerabilitySummary.summary) {
            return this.vulnerabilitySummary.summary.summary;
        }

        return null;
    }

    get criticalCount(): number {
        if (this.sevSummary) {
            return this.sevSummary[VULNERABILITY_SEVERITY.CRITICAL];
        }

        return 0;
    }
    duration(): string {
        if (this.vulnerabilitySummary && this.vulnerabilitySummary.duration) {
            let str = '';
            const min = Math.floor(this.vulnerabilitySummary.duration / MIN);
            if (min) {
                str += min + ' ' + MIN_STR;
            }
            const sec = this.vulnerabilitySummary.duration % MIN;
            if (sec) {
                str += sec + ' ' + SEC_STR;
            }
            return str;
        }
        return '0';
    }
    get highCount(): number {
        if (this.sevSummary) {
            return this.sevSummary[VULNERABILITY_SEVERITY.HIGH];
        }

        return 0;
    }

    get mediumCount(): number {
        if (this.sevSummary) {
            return this.sevSummary[VULNERABILITY_SEVERITY.MEDIUM];
        }

        return 0;
    }

    get lowCount(): number {
        if (this.sevSummary) {
            return this.sevSummary[VULNERABILITY_SEVERITY.LOW];
        }

        return 0;
    }

    get noneCount(): number {
        if (
            this.vulnerabilitySummary &&
            this.vulnerabilitySummary.summary &&
            this.vulnerabilitySummary.summary.summary
        ) {
            return this.vulnerabilitySummary.summary.summary[
                VULNERABILITY_SEVERITY.NONE
            ];
        }

        return 0;
    }
    public get completePercent(): string {
        return this.vulnerabilitySummary
            ? `${this.vulnerabilitySummary.complete_percent}%`
            : '0%';
    }
    isLimitedSuccess(): boolean {
        return (
            this.vulnerabilitySummary &&
            this.vulnerabilitySummary.complete_percent < SUCCESS_PCT
        );
    }
    get completeTimestamp(): Date {
        return this.vulnerabilitySummary && this.vulnerabilitySummary.end_time
            ? this.vulnerabilitySummary.end_time
            : new Date();
    }
    get isCritical(): boolean {
        return (
            this.vulnerabilitySummary &&
            VULNERABILITY_SEVERITY.CRITICAL ===
                this.vulnerabilitySummary.severity
        );
    }
    get isHigh(): boolean {
        return (
            this.vulnerabilitySummary &&
            VULNERABILITY_SEVERITY.HIGH === this.vulnerabilitySummary.severity
        );
    }
    get isMedium(): boolean {
        return (
            this.vulnerabilitySummary &&
            VULNERABILITY_SEVERITY.MEDIUM === this.vulnerabilitySummary.severity
        );
    }
    get isLow(): boolean {
        return (
            this.vulnerabilitySummary &&
            VULNERABILITY_SEVERITY.LOW === this.vulnerabilitySummary.severity
        );
    }
    get isNone(): boolean {
        return (
            this.vulnerabilitySummary &&
            VULNERABILITY_SEVERITY.NONE ===
                this.vulnerabilitySummary.severity &&
            this.total > 0
        );
    }
    get noVulnerability(): boolean {
        return this.total === 0;
    }
    getClass(): string {
        if (this.vulnerabilitySummary && this.vulnerabilitySummary.severity) {
            if (this.isCritical) {
                return CLASS_MAP.CRITICAL;
            }
            if (this.isHigh) {
                return CLASS_MAP.HIGH;
            }
            if (this.isMedium) {
                return CLASS_MAP.MEDIUM;
            }
            if (this.isLow) {
                return CLASS_MAP.LOW;
            }
            if (this.isNone) {
                return CLASS_MAP.NONE;
            }
        }
        return null;
    }
    passMetadataToChart() {
        return [
            {
                text: 'VULNERABILITY.SEVERITY.CRITICAL',
                value: this.criticalCount ? this.criticalCount : 0,
                color: SeverityColors.CRITICAL,
            },
            {
                text: 'VULNERABILITY.SEVERITY.HIGH',
                value: this.highCount ? this.highCount : 0,
                color: SeverityColors.HIGH,
            },
            {
                text: 'VULNERABILITY.SEVERITY.MEDIUM',
                value: this.mediumCount ? this.mediumCount : 0,
                color: SeverityColors.MEDIUM,
            },
            {
                text: 'VULNERABILITY.SEVERITY.LOW',
                value: this.lowCount ? this.lowCount : 0,
                color: SeverityColors.LOW,
            },
            {
                text: 'VULNERABILITY.SEVERITY.NONE',
                value: this.noneCount ? this.noneCount : 0,
                color: SeverityColors.NA,
            },
        ];
    }
    isThemeLight() {
        return localStorage.getItem(HAS_STYLE_MODE) === StyleMode.LIGHT;
    }
    getScannerInfo(): string {
        if (this.scanner) {
            if (this.scanner.name && this.scanner.version) {
                return `${this.scanner.name}@${this.scanner.version}`;
            }
            if (this.scanner.name && !this.scanner.version) {
                return `${this.scanner.name}`;
            }
        }
        return '';
    }
}
