/*
 * 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, ViewChild} from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ToastrService } from 'ngx-toastr';

import {
  HealthStatusService,
  ManageEnvironmentsService,
  BackupService,
  UserResourceService,
  StorageService
} from '../../core/services';

import { EnvironmentModel, GeneralEnvironmentStatus } from './management.model';
import { HTTP_STATUS_CODES } from '../../core/util';
import { BackupDilogComponent } from './backup-dilog/backup-dilog.component';
import { SsnMonitorComponent } from './ssn-monitor/ssn-monitor.component';
import { ManageEnvironmentComponent } from './manage-environment/manage-environment-dilog.component';
import { EndpointsComponent } from './endpoints/endpoints.component';
import { ExploratoryModel } from '../../resources/resources-grid/resources-grid.model';

import { EnvironmentsDataService } from './management-data.service';
import { ProjectService } from '../../core/services';
import {ConfirmationDialogComponent, ConfirmationDialogType} from '../../shared/modal-dialog/confirmation-dialog';
import {ManagementGridComponent, ReconfirmationDialogComponent} from './management-grid/management-grid.component';
import {FolderTreeComponent} from '../../resources/bucket-browser/folder-tree/folder-tree.component';

@Component({
  selector: 'environments-management',
  templateUrl: './management.component.html',
  styleUrls: ['./management.component.scss']
})
export class ManagementComponent implements OnInit {
  public user: string = '';
  public healthStatus: GeneralEnvironmentStatus;
  // public anyEnvInProgress: boolean = false;
  public dialogRef: any;
  public selected: any[] = [];
  public isActionsOpen: boolean = false;
  public selectedRunning: any[];
  public selectedStopped: any[];

  @ViewChild(ManagementGridComponent, {static: true}) managementGrid;


  constructor(
    public toastr: ToastrService,
    public dialog: MatDialog,
    private healthStatusService: HealthStatusService,
    private backupService: BackupService,
    private manageEnvironmentsService: ManageEnvironmentsService,
    private userResourceService: UserResourceService,
    private storageService: StorageService,
    private environmentsDataService: EnvironmentsDataService,
    private projectService: ProjectService
  ) { }

  ngOnInit() {
    this.buildGrid();
    this.user = this.storageService.getUserName();
  }

  public buildGrid() {
    this.getEnvironmentHealthStatus();
    this.environmentsDataService.updateEnvironmentData();
  }

  public refreshGrid() {
     this.buildGrid();
  }

  public manageEnvironmentAction($event) {
    this.manageEnvironmentsService
      .environmentManagement(
        $event.environment.user,
        $event.action,
        $event.environment.project,
        $event.environment.type === 'edge node' ? 'edge' : $event.environment.name,
        $event.resource ? $event.resource.computational_name : null
      ).subscribe(
        () => this.buildGrid(),
        error => this.toastr.error('Environment management failed!', 'Oops!'));
  }

  // showBackupDialog() {
  //   this.dialog.open(BackupDilogComponent, { panelClass: 'modal-sm' });
  // }

  showEndpointsDialog() {
    this.dialog.open(EndpointsComponent, { panelClass: 'modal-xl-s' })
      .afterClosed().subscribe(result => result && this.buildGrid());
  }

  openManageEnvironmentDialog() {
    this.projectService.getProjectsList().subscribe(projectsList => {
      this.getTotalBudgetData().subscribe(total => {
        this.dialogRef = this.dialog.open(ManageEnvironmentComponent, { data: { projectsList, total }, panelClass: 'modal-xl-s' });
        this.dialogRef.afterClosed().subscribe(result => result && this.setBudgetLimits(result));
      }, () => this.toastr.error('Failed users list loading!', 'Oops!'));
    });
  }

  // openSsnMonitorDialog() {
  //   this.dialog.open(SsnMonitorComponent, { panelClass: 'modal-lg' });
  // }
  //
  // isEnvironmentsInProgress(exploratory): boolean {
  //   return exploratory.some(item => {
  //     return item.exploratory.some(el => el.status === 'creating' || el.status === 'starting' ||
  //       el.resources.some(elem => elem.status === 'creating' || elem.status === 'starting' || elem.status === 'configuring'));
  //   });
  // }

  setBudgetLimits($event) {
    if ($event.projects.length) {
      this.projectService.updateProjectsBudget($event.projects).subscribe((result: any) => {
        if ($event.isTotalChanged) {
          this.healthStatusService.updateTotalBudgetData($event.total).subscribe((res: any) => {
            result.status === HTTP_STATUS_CODES.OK
            && res.status === HTTP_STATUS_CODES.NO_CONTENT
            && this.toastr.success('Budget limits updated!', 'Success!');
            this.buildGrid();
          });
        } else {
          result.status === HTTP_STATUS_CODES.OK && this.toastr.success('Budget limits updated!', 'Success!');
          this.buildGrid();
        }

      }, error => this.toastr.error(error.message, 'Oops!'));
    } else {
      this.healthStatusService.updateTotalBudgetData($event.total).subscribe((res: any) => {
        res.status === HTTP_STATUS_CODES.NO_CONTENT
        && this.toastr.success('Budget limits updated!', 'Success!');
        this.buildGrid();
      });
    }
    }


  // manageEnvironment(event: { action: string, project: any }) {
  //   if (event.action === 'stop')
  //     this.projectService.stopProjectAction(event.project.project_name)
  //       .subscribe(() => this.handleSuccessAction(event.action), error => this.toastr.error(error.message, 'Oops!'));
  //
  //   if (event.action === 'terminate')
  //     this.projectService.deleteProject(event.project.project_name)
  //       .subscribe(() => this.handleSuccessAction(event.action), error => this.toastr.error(error.message, 'Oops!'));
  // }

  // handleSuccessAction(action) {
  //   this.toastr.success(`Action ${action} is processing!`, 'Processing!');
  //   this.projectService.getProjectsManagingList().subscribe(data => {
  //     this.dialogRef.componentInstance.data.projectsList = data;
  //     this.dialogRef.componentInstance.setProjectsControl();
  //   });
  //   this.buildGrid();
  // }
  //
  // get creatingBackup(): boolean {
  //   return this.backupService.inProgress;
  // }

  // private getExploratoryList() {
  //   this.userResourceService.getUserProvisionedResources()
  //     .subscribe((result) => this.anyEnvInProgress = this.isEnvironmentsInProgress(
  //       ExploratoryModel.loadEnvironments(result)));
  // }

  private getEnvironmentHealthStatus() {
    this.healthStatusService
      .getEnvironmentStatuses()
      .subscribe((status: GeneralEnvironmentStatus) => {
        this.healthStatus = status;
        // this.getExploratoryList();
      });
  }

  // private getActiveUsersList() {
  //   return this.healthStatusService.getActiveUsers();
  // }

  private getTotalBudgetData() {
    return this.healthStatusService.getTotalBudgetData();
  }

  public selectedList($event) {
    this.selected = $event;
    if (this.selected.length === 0) {
      this.isActionsOpen = false;
    }

    this.selectedRunning = this.selected.filter(item => item.status === 'running');
    this.selectedStopped = this.selected.filter(item => item.status === 'stopped');
  }

  public toogleActions() {
    this.isActionsOpen = !this.isActionsOpen;
  }

  toggleResourceAction($event): void {
    const {environment, action, resource} = $event;
    if (resource) {
      const resource_name = resource ? resource.computational_name : environment.name;
      this.dialog.open(ReconfirmationDialogComponent, {
        data: { action, resource_name, user: environment.user, type: 'cluster'},
        width: '550px', panelClass: 'error-modalbox'
      }).afterClosed().subscribe(result => {
        result && this.manageEnvironmentAction({ action, environment, resource });
      });
    } else {
      let notebooks = this.selected.length ? this.selected : [environment];
      if (action === 'stop') {
        notebooks = notebooks.filter(note => note.status !== 'stopped');
        this.dialog.open(ReconfirmationDialogComponent, {
          data: { notebooks: notebooks, type: 'notebook', action },
          width: '550px', panelClass: 'error-modalbox'
        }).afterClosed().subscribe((res) => {
          if (res) {
            notebooks.forEach((env) => {
              this.manageEnvironmentsService.environmentManagement(env.user, 'stop', env.project, env.name)
                .subscribe(response => {
                    this.buildGrid();
                  },
                  error => console.log(error)
                );
            });
            this.clearSelection();
          } else {
            this.clearSelection();
          }
          this.isActionsOpen = false;
        });
      } else if (action === 'terminate') {
        this.dialog.open(ReconfirmationDialogComponent, {
          data: { notebooks: notebooks, type: 'notebook', action }, width: '550px', panelClass: 'error-modalbox'
        }).afterClosed().subscribe((res) => {
          if (res) {
            notebooks.forEach((env) => {
              this.manageEnvironmentsService.environmentManagement(env.user, 'terminate', env.project, env.name)
                .subscribe(
                  response => {
                    this.buildGrid();
                  },
                  error => console.log(error)
                );
            });
            this.clearSelection();
          } else {
            this.clearSelection();
          }
          this.isActionsOpen = false;
        });
      // } else if (action === 'run') {
      //   this.healthStatusService.runEdgeNode().subscribe(() => {
      //     this.buildGrid();
      //     this.toastr.success('Edge node is starting!', 'Processing!');
      //   }, () => this.toastr.error('Edge Node running failed!', 'Oops!'));
      // } else if (action === 'recreate') {
      //   this.healthStatusService.recreateEdgeNode().subscribe(() => {
      //     this.buildGrid();
      //     this.toastr.success('Edge Node recreation is processing!', 'Processing!');
      //   }, () => this.toastr.error('Edge Node recreation failed!', 'Oops!'));
      }
    }
  }

  private clearSelection() {
    this.selected = [];
    this.isActionsOpen = false;
    if (this.managementGrid.selected && this.managementGrid.selected.length !== 0) {
      this.managementGrid.selected.forEach(item => item.isSelected = false);
      this.managementGrid.selected = [];
    }
  }


  public resourseAction(action) {
      this.toggleResourceAction({environment: this.selected, action: action});
  }
}
