import { Component, Input, Output, EventEmitter, ViewChild, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
import { map, catchError, finalize } from "rxjs/operators";
import { Observable, throwError as observableThrowError, of } from "rxjs";
import { Configuration } from '../config';
import {
    ScanningResultService,
    SystemInfo,
    SystemInfoService,
    ConfigurationService
} from '../../service/index';
import { ErrorHandler } from '../../error-handler/index';
import { isEmptyObject, clone} from '../../utils';
import { TranslateService } from '@ngx-translate/core';
import { ClairDetail } from '../../service/interface';
import { ScanAllRepoService } from './scanAll.service';
import { OriginCron } from '../../service/interface';
import { CronScheduleComponent } from "../../cron-schedule/cron-schedule.component";
const ONE_HOUR_SECONDS: number = 3600;
const ONE_DAY_SECONDS: number = 24 * ONE_HOUR_SECONDS;
const SCHEDULE_TYPE_NONE = "None";
@Component({
    selector: 'vulnerability-config',
    templateUrl: './vulnerability-config.component.html',
    styleUrls: ['./vulnerability-config.component.scss', '../registry-config.component.scss']
})
export class VulnerabilityConfigComponent implements OnInit {
    onGoing: boolean;
    _localTime: Date = new Date();
    originCron: OriginCron;
    schedule: any;
    onSubmitting: boolean = false;
    config: Configuration;
    openState: boolean = false;
    getLabelCurrent: string;

    @ViewChild(CronScheduleComponent, {static: false})
    CronScheduleComponent: CronScheduleComponent;

    @Input()

    @Input() showSubTitle: boolean = false;
    @Input() showScanningNamespaces: boolean = false;
    @Output() loadingStatus = new EventEmitter<boolean>();
    systemInfo: SystemInfo;

    constructor(
        // private scanningService: ScanningResultService,
        private scanningService: ScanAllRepoService,
        private errorHandler: ErrorHandler,
        private translate: TranslateService,
        private systemInfoService: SystemInfoService,
        private configService: ConfigurationService
    ) { }

    get scanAvailable(): boolean {
        return !this.onSubmitting;
    }

    getScanText() {
        this.translate.get('CONFIG.SCANNING.SCAN_ALL').subscribe((res: string) => {
          this.getLabelCurrent = res;
        });
    }

    get updatedTimestamp(): Date {
        if (this.systemInfo &&
            this.systemInfo.clair_vulnerability_status &&
            this.systemInfo.clair_vulnerability_status.overall_last_update > 0) {
            return this.convertToLocalTime(this.systemInfo.clair_vulnerability_status.overall_last_update);
        }

        return null;
    }

    get namespaceTimestamps(): ClairDetail[] {
        if (this.systemInfo &&
            this.systemInfo.clair_vulnerability_status &&
            this.systemInfo.clair_vulnerability_status.details &&
            this.systemInfo.clair_vulnerability_status.details.length > 0) {
            return this.systemInfo.clair_vulnerability_status.details;
        }

        return [];
    }

    getSchedule() {
      this.onGoing = true;
      this.scanningService.getSchedule()
      .pipe(finalize(() => {
        this.onGoing = false;
        this.loadingStatus.emit(this.onGoing);
      }))
      .subscribe(schedule => {
        this.initSchedule(schedule);
      }, error => {
        this.errorHandler.error(error);
      });
    }

      public initSchedule(schedule: any) {
        if (schedule && schedule.schedule !== null) {
          this.schedule = schedule;
          this.originCron = this.schedule.schedule;
        } else {
          this.originCron = {
            type: SCHEDULE_TYPE_NONE,
            cron: ''
          };
        }
      }
    @ViewChild("systemConfigFrom", {static: false}) systemSettingsForm: NgForm;

    get isValid(): boolean {
        return this.systemSettingsForm && this.systemSettingsForm.valid;
    }

    get isClairDBFullyReady(): boolean {
        return this.systemInfo &&
            this.systemInfo.clair_vulnerability_status &&
            this.systemInfo.clair_vulnerability_status.overall_last_update > 0;
    }

    ngOnInit(): void {
      this.getSystemInfo();
      this.getScanText();
      this.getSchedule();
    }

    getSystemInfo(): void {
      this.systemInfoService.getSystemInfo()
         .subscribe((info: SystemInfo) => (this.systemInfo = info)
         , error => this.errorHandler.error(error));
    }

    convertToLocalTime(utcTime: number): Date {
        let dt: Date = new Date();
        dt.setTime(utcTime * 1000);

        return dt;
    }

    scanNow(): void {
        if (this.onSubmitting) {
            return; // Aoid duplicated submitting
        }

        if (!this.scanAvailable) {
            return; // Aoid page hacking
        }

        this.onSubmitting = true;
        this.scanningService.manualScan()
            .subscribe(() => {
                this.translate.get("CONFIG.SCANNING.TRIGGER_SCAN_ALL_SUCCESS").subscribe((res: string) => {
                    this.errorHandler.info(res);
                });

                // Update system info
                this.systemInfoService.getSystemInfo()
                .subscribe(() => {
                  this.onSubmitting = false;
                }, error => {
                  this.onSubmitting = false;
                });
            }
            , error => {
                if (error && error.status && error.status === 412) {
                    this.translate.get("CONFIG.SCANNING.TRIGGER_SCAN_ALL_FAIL", { error: '' + error }).subscribe((res: string) => {
                        this.errorHandler.error(res);
                    });
                } else {
                    this.errorHandler.error(error);
                }
                this.onSubmitting = false;
            });
    }

    reset(cron): void {
        this.schedule = {
            schedule: {
              type: this.CronScheduleComponent.scheduleType,
              cron: cron
            }
        };
    }

    scanAll(cron: string): void {
        let schedule = this.schedule;
        if (schedule && schedule.schedule && schedule.schedule.type !== SCHEDULE_TYPE_NONE) {
          this.scanningService.putSchedule(this.CronScheduleComponent.scheduleType, cron)
          .subscribe(response => {
              this.translate
                .get("CONFIG.SAVE_SUCCESS")
                .subscribe((res) => {
                  this.errorHandler.info(res);
                  this.CronScheduleComponent.resetSchedule();
                });
              this.reset(cron);
            },
            error => {
              this.errorHandler.error(error);
            }
          );
        } else {
          this.scanningService.postSchedule(this.CronScheduleComponent.scheduleType, cron)
            .subscribe(response => {
              this.translate.get("CONFIG.SAVE_SUCCESS").subscribe((res) => {
                this.errorHandler.info(res);
                this.CronScheduleComponent.resetSchedule();
              });
              this.reset(cron);
            },
            error => {
              this.errorHandler.error(error);
            }
          );
        }
    }
}
