/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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, OnInit, Inject, HostListener, OnDestroy, ViewChild, ElementRef} from '@angular/core';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import {HealthStatusService, AppRoutingService, EndpointService} from '../../core/services';
import {MatTabChangeEvent} from '@angular/material/tabs';
import {Router} from '@angular/router';
import {ConfigurationService} from '../../core/services/configutration.service';
import 'brace';
import 'brace/mode/yaml';
import {ToastrService} from 'ngx-toastr';
import {Observable, Subject} from 'rxjs';
import {takeUntil} from 'rxjs/operators';
import { EnvironmentsDataService } from '../management/management-data.service';
import { EnvironmentModel } from '../management/management.model';

@Component({
  selector: 'datalab-configuration',
  templateUrl: './configuration.component.html',
  styleUrls: ['./configuration.component.scss']
})
export class ConfigurationComponent implements OnInit, OnDestroy {
  @ViewChild('selfEditor') selfEditor: ElementRef<HTMLElement>;
  @ViewChild('provEditor') provEditor: ElementRef<HTMLElement>;
  @ViewChild('billingEditor') billingEditor: ElementRef<HTMLElement>;
  private unsubscribe$ = new Subject();
  private healthStatus: any;
  public activeTab = {index: 0};
  public activeService: string;
  public services = {
    'self-service': {label: 'Self-service', selected: false, config: '', serverConfig: '', isConfigChanged: false},
    'provisioning': {label: 'Provisioning', selected: false, config: '', serverConfig: '', isConfigChanged: false},
    'billing': {label: 'Billing', selected: false, config: '', serverConfig: '', isConfigChanged: false},
  };

  public messagesStatus = {
    success: [],
    error: [],
    counter: 0
  };
  
  public environmentStatuses = {};
  public environments = [];
  public ingStatuses = ['creating', 'configuring', 'reconfiguring', 'creating image', 'stopping', 'starting', 'terminating'];

  private confirmMessages = {
    restartService: 'Restarting services will make DataLab unavailable for some time.',
    discardChanges: 'Discard all unsaved changes.',
    saveChanges: 'After you save changes you need to restart service.',
  };
  public activeEndpoint: string;
  public endpoints: Array<string> | any;

  @HostListener('window:keydown', ['$event'])
  onKeyDown(event: KeyboardEvent) {
    if ((event.metaKey || event.ctrlKey) &&
      event.key === 's' &&
      this.activeTab.index !== 0 &&
      this.router.url === '/configuration' &&
      this.services[this.activeService].config !== this.services[this.activeService].serverConfig
    ) {
      this.action('save');
      event.preventDefault();
    }
  }

  constructor(
    private healthStatusService: HealthStatusService,
    private appRoutingService: AppRoutingService,
    private endpointService: EndpointService,
    private configurationService: ConfigurationService,
    private environmentsDataService: EnvironmentsDataService,
    private router: Router,
    public dialog: MatDialog,
    public toastr: ToastrService,
  ) { }

  ngOnInit() {
    this.getEnvironmentHealthStatus();
    this.getEndpoints()
      .subscribe(endpoints => {
      this.endpoints = endpoints;
      
      this.endpoints = this.endpoints.map(endpoint => ({name: endpoint.name, status: endpoint.status }));

      this.activeEndpoint = this.endpoints[0].name;
      this.getServicesConfig(this.activeEndpoint);
    });

    this.environmentsDataService.getEnvironmentDataDirect().subscribe((data: any) => {
      this.environments = EnvironmentModel.loadEnvironments(data);
      this.environments.map(env => {
        this.checkResource(env.status, env.endpoint);
        if(env.resources?.length > 0) {
          env.resources.map(resource => {
            this.checkResource(resource.status, env.endpoint);
          })
        }
      });
    });
  }

  ngOnDestroy() {
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
  }

  public checkResource(resourceStatus: string, endpoint: string) {
    if( this.ingStatuses.includes(resourceStatus) ) {
      if(!this.environmentStatuses[endpoint]) {
        this.environmentStatuses[endpoint] = [];
        this.environmentStatuses[endpoint].push(resourceStatus);
      } else {
        this.environmentStatuses[endpoint].push(resourceStatus);
      }
    }
  }

  private getEnvironmentHealthStatus(): void {
    this.healthStatusService.getEnvironmentHealthStatus()
      .pipe(
        takeUntil(this.unsubscribe$)
      )
      .subscribe((result: any) => {
          this.healthStatus = result;
          !this.healthStatus.admin && !this.healthStatus.projectAdmin && this.appRoutingService.redirectToHomePage();
          }
      );
  }

  private getEndpoints(): Observable<{}> {
    return this.endpointService.getEndpointsData();
  }

  public refreshConfig(): void {
    this.getServicesConfig(this.activeEndpoint);
  }

  public action(action: string): void {
    this.dialog.open(SettingsConfirmationDialogComponent, { data: {
        action: action, 
        message: action === 'discard' ? this.confirmMessages.discardChanges : this.confirmMessages.saveChanges,
        environmentStatuses: this.environmentStatuses,
        activeEndpoint: this.activeEndpoint
      }, panelClass: 'modal-sm' })
      .afterClosed().subscribe(result => {
      if (result && action === 'save') this.setServiceConfig(this.activeService, this.services[this.activeService].config);
      if (result && action === 'discard') this.services[this.activeService].config = this.services[this.activeService].serverConfig;
      this.configUpdate(this.activeService);
    });
  }

  private getServicesConfig(endpoint): void {
      this.configurationService.getServiceSettings(endpoint)
        .pipe(
          takeUntil(this.unsubscribe$)
        )
        .subscribe(config => {
          for (const service in this.services) {
            const file = `${service}.yml`;
            this.services[service].config = config[file];
            this.services[service].serverConfig = config[file];
            this.configUpdate(service);
          }
        }
      );

    this.clearSelectedServices();
  }

  private setServiceConfig(service: string, config: string): void {
    this.configurationService.setServiceConfig(service, config, this.activeEndpoint)
      .pipe(
        takeUntil(this.unsubscribe$)
      )
      .subscribe(res => {
      this.getServicesConfig(this.activeEndpoint);
      this.toastr.success('Service configuration saved!', 'Success!');
      },
      error => this.toastr.error( error.message || 'Service configuration is not saved', 'Oops!')
    );
  }

  refreshServiceEditor(editor: ElementRef<HTMLElement>) {
    if(editor) {
      editor.nativeElement.children[3].scrollTop = 100;
      editor.nativeElement.children[3].scrollTop = 0;
    }
  }

  public tabChanged(tabChangeEvent: MatTabChangeEvent): void {
    this.activeTab = tabChangeEvent;
    
    if (this.activeTab.index === 1 && this.activeEndpoint === 'local') {
      this.activeService = 'self-service';
      this.refreshServiceEditor(this.selfEditor);
    } else if ((this.activeEndpoint !== 'local' && this.activeTab.index === 1) || 
            (this.activeTab.index === 2 && this.activeEndpoint === 'local')) {
      this.activeService = 'provisioning';
      this.refreshServiceEditor(this.provEditor);
    } else if ((this.activeEndpoint !== 'local' && this.activeTab.index === 2) || 
            (this.activeTab.index === 3 && this.activeEndpoint === 'local')) {
      this.activeService = 'billing';
      this.refreshServiceEditor(this.billingEditor);
    } else {
      this.activeService = '';
    }

    if (!!this.activeService) {
      if (this.services[this.activeService].config !== this.services[this.activeService].serverConfig) {
        this.dialog.open(SettingsConfirmationDialogComponent, { data: {
            action: 'Was changed',
            environmentStatuses: this.environmentStatuses,
            activeEndpoint: this.activeEndpoint
          }, panelClass: 'modal-sm' })
          .afterClosed().subscribe(result => {
          if (result) {
            this.services[this.activeService].serverConfig = this.services[this.activeService].config;
          } else {
            this.services[this.activeService].config = this.services[this.activeService].serverConfig;
          }
        });
      }
    }
    this.clearSelectedServices();
  }

  private clearSelectedServices(): void {
    Object.keys(this.services).forEach(service => this.services[service].selected = false);
  }

  public toggleSettings(service): void {
    this.services[service].selected = !this.services[service].selected;
  }

  public restartSingleService(ui: boolean, prov: boolean, billing: boolean, serviceName) {
    this.configurationService.restartServices(ui, prov, billing, this.activeEndpoint)
      .pipe(
        takeUntil(this.unsubscribe$),
      )
      .subscribe(
        res => {
          this.messagesStatus.success.push(serviceName);
          this.messagesStatus.counter -= 1;
        },
        error => {
          if (serviceName === 'Self-service') {
            this.messagesStatus.success.push(serviceName);
          } else {
            this.messagesStatus.error.push(serviceName);
          }
          this.messagesStatus.counter -= 1;
        }
      );
  }

  public restartServices(): void  {
    const selectedServices = [];
    for (const service in this.services) {
      if (this.services[service].selected) {
        selectedServices.push(service);
      }
    }

    this.dialog.open(
      SettingsConfirmationDialogComponent, 
      { 
        data: {
          action: 'restart', 
          services: selectedServices,
          environmentStatuses: this.environmentStatuses,
          activeEndpoint: this.activeEndpoint 
        }, 
        panelClass: 'modal-sm' 
      })
      .afterClosed().subscribe(result => {
        if (result) {
          this.messagesStatus.error = [];
          this.messagesStatus.success = [];
          
          if(this.environmentStatuses[this.activeEndpoint] && this.services['provisioning'].selected) {
            this.services['provisioning'].selected = false;
          }

          if(this.services['self-service'].selected) {
            this.messagesStatus.counter += 1;
            this.restartSingleService(true, false, false, 'Self-service')
          } 
          if(this.services['provisioning'].selected) {
            this.messagesStatus.counter += 1;
            this.restartSingleService(false, true, false, 'Provisioning service')
          } 
          if(this.services['billing'].selected) {
            this.messagesStatus.counter += 1;
            this.restartSingleService(false, false, true, 'Billing service')
          }

          let timer = setInterval(() => {
            
            if(this.messagesStatus.counter === 0) {
              for(let key in this.messagesStatus) {
                if(key === 'error' && this.messagesStatus[key].length > 0) {
                  this.toastr.error(`${this.messagesStatus[key].join(', ')} restarting failed`, 'Oops!');
                } else if(key === 'success' && this.messagesStatus[key].length > 0) {
                  this.toastr.success(`${this.messagesStatus[key].join(', ')} restarting started!`, 'Success!');
                }
              }
              clearInterval(timer);
            } 
          }, 200);
          this.clearSelectedServices();
        } else {
          this.clearSelectedServices();
        }
    });
  }

  public configUpdate(service: string): void {
    this.services[service].isConfigChanged = this.services[service].config !== this.services[service].serverConfig;
  }

  public isServiceSelected(): boolean {
    return Object.keys(this.services).every(service => !this.services[service].selected);
  }


  public setActiveEndpoint(endpoint) {
    this.activeEndpoint = endpoint;
    this.getServicesConfig(this.activeEndpoint);
    this.activeTab.index = 0;
  }
}

@Component({
  selector: 'confirm-dialog',
  template: `
  <div id="dialog-box">
    <div class="dialog-header">
      <h4 class="modal-title"><span class="capitalize">{{ data.action }}</span> <span *ngIf="data.action === 'save' || data.action === 'discard'"> changes</span><span *ngIf="data.action === 'restart'">
        service<span *ngIf="data.services.length > 1">s</span>
      </span></h4>
      <button type="button" class="close" (click)="dialogRef.close()">&times;</button>
    </div>

    <div mat-dialog-content class="content">
      <ng-template [ngIf]="data.action === 'restart' && !data.environmentStatuses[data.activeEndpoint]?.length" ]>
        <span class="strong">{{data.services.join(', ') | titlecase}}</span> 
        <span class="strong" *ngIf="data.services.length > 1 || (data.services.length === 1 && data.services[0] !== 'self-service')"> service</span>
        <span class="strong" [hidden]="(data.services.length < 2) || data.services.length === 2 && data.services[0] === 'self-service'">s</span>: restarting will make DataLab unavailable for some time.
      </ng-template>

      <ng-template [ngIf]="data.action === 'restart' && data.environmentStatuses[data.activeEndpoint]?.length && filterProvisioning.length" ]>
        <span class="strong" >{{filterProvisioning.join(', ') | titlecase}}</span> 
        <span class="strong" *ngIf="filterProvisioning.length > 1 || (filterProvisioning.length === 1 && filterProvisioning[0] !== 'self-service')"> service</span>
        <span [hidden]="(filterProvisioning.length < 2) || filterProvisioning.length === 2 && filterProvisioning[0] === 'self-service'">s</span>: restarting will make DataLab unavailable for some time.
      </ng-template>

      <ng-template [ngIf]="data.action === 'restart' && data.environmentStatuses[data.activeEndpoint]?.length && (data?.services?.includes('provisioning') || !filterProvisioning.length)">
        <div class="warning" [ngStyle]="data?.services?.includes('provisioning') && data.services?.length > 1 && {'margin-top': '10px'}">
        <span>Provisioning service: </span>can not be restarted because one of resources is in processing stage. Please try again later.
        </div>
      </ng-template>

      <ng-template [ngIf]="data.action === 'discard'" ]>Discard all unsaved changes.</ng-template>
      <ng-template [ngIf]="data.action === 'save'" ]>After you save changes you need to restart service.</ng-template>
    </div>
    <div class="text-center " *ngIf="!data.environmentStatuses[data.activeEndpoint]?.length || (data.environmentStatuses[data.activeEndpoint]?.length && (!data?.services?.includes('provisioning') || filterProvisioning?.length))">
      <p class="strong">Do you want to proceed?</p>
    </div>
    <div class="text-center m-top-20 pb-25" *ngIf="!data.environmentStatuses[data.activeEndpoint]?.length || (data.environmentStatuses[data.activeEndpoint]?.length && (!data?.services?.includes('provisioning') || filterProvisioning.length))">
      <button type="button" class="butt" mat-raised-button (click)="dialogRef.close()">No</button>
      <button type="button" class="butt butt-success" mat-raised-button (click)="dialogRef.close(true)">Yes</button>
    </div>
    <div class="text-center m-top-20 pb-25" *ngIf="data.action === 'restart' && data.environmentStatuses[data.activeEndpoint]?.length && data?.services?.includes('provisioning') && data.services.length === 1">
      <button type="button" class="butt" mat-raised-button (click)="dialogRef.close()">Close</button>
    </div>
  </div>
  `,
  styles: [
    `
      .content { color: #718ba6; padding: 20px 50px; font-size: 14px; font-weight: 400; margin: 0; }
      header { display: flex; justify-content: space-between; color: #607D8B; }
      header h4 i { vertical-align: bottom; }
      header a i { font-size: 20px; }
      header a:hover i { color: #35afd5; cursor: pointer; }
      .content{padding: 35px 30px 30px 30px; text-align: center;}
      label{cursor: pointer;}
      .warning{color: #EF5C4B;}
      .warning span {font-weight: 600;}`
  ]
})

export class SettingsConfirmationDialogComponent implements OnInit {
  filterProvisioning = [];
  constructor(
    public dialogRef: MatDialogRef<SettingsConfirmationDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: any
  ) {
  }
  ngOnInit() {
    this.filterProvisioning = this.data?.services?.filter(service => service !== 'provisioning');
  }
}


