/*
 * 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 } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { ToastrService } from 'ngx-toastr';

import { UserResourceService } from '../../../core/services';
import { HTTP_STATUS_CODES, PATTERNS } from '../../../core/util';
import { DICTIONARY } from '../../../../dictionary/global.dictionary';

@Component({
  selector: 'datalab-ami-create-dialog',
  templateUrl: './ami-create-dialog.component.html',
  styleUrls: ['./ami-create-dialog.component.scss']
})
export class AmiCreateDialogComponent implements OnInit {
  readonly DICTIONARY = DICTIONARY;
  public notebook: any;
  public createAMIForm: FormGroup;
  public provider: string;
  delimitersRegex = /[-_]?/g;
  imagesList: any;

  constructor(
    @Inject(MAT_DIALOG_DATA) public data: any,
    public toastr: ToastrService,
    public dialogRef: MatDialogRef<AmiCreateDialogComponent>,
    private _userResource: UserResourceService,
    private _fb: FormBuilder,
  ) { }

  ngOnInit() {
    this.notebook = this.data;
    this.provider = this.data.cloud_provider;

    this.initFormModel();
    this._userResource.getImagesList(this.data.project).subscribe(res => this.imagesList = res);
  }

  public assignChanges(data) {
    this._userResource.createAMI(data).subscribe(
      response => response.status === HTTP_STATUS_CODES.ACCEPTED && this.dialogRef.close(true),
      error => this.toastr.error(error.message || `Image creation failed!`, 'Oops!'));
  }

  private initFormModel(): void {
    this.createAMIForm = this._fb.group({
      name: ['', [
        Validators.required, 
        Validators.pattern(PATTERNS.namePattern), 
        Validators.maxLength(10), 
        this.checkDuplication.bind(this)
      ]],
      description: [''],
      exploratory_name: [this.notebook.name],
      project_name: [this.notebook.project]
    });
  }

  private checkDuplication(control) {
    if (control.value) {
      return this.isDuplicate(control.value) ? { duplication: true } : null;
    }
  }

  private isDuplicate(value: string) {
    for (let index = 0; index < this.imagesList.length; index++) {
      if (this.delimitersFiltering(value) === this.delimitersFiltering(this.imagesList[index].name)) {
        return true;
      }
    }
    return false;
  }

  private delimitersFiltering(resource): string {
    return resource.replace(this.delimitersRegex, '').toString().toLowerCase();
  }
}
