/*
 * 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, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ExperimentTemplate } from '@submarine/interfaces/experiment-template';
import { ExperimentFormService } from '@submarine/services/experiment.form.service';
import { ExperimentService } from '@submarine/services/experiment.service';
import { Subscription } from 'rxjs';
import { ExperimentTemplateSubmit } from '@submarine/interfaces/experiment-template-submit';
import { NzMessageService } from 'ng-zorro-antd';

interface ParsedTemplate {
  templateParams: {
    name: string;
    required: string;
    description: string;
    value: string;
  }[];
  experimentName: string;
  experimentNamespace: string;
  experimentCommand: string;
  experimentImage: string;
  experimentVars: string;
}

interface TemplateTable {
  [templateName: string]: ParsedTemplate;
}

@Component({
  selector: 'submarine-experiment-predefined-form',
  templateUrl: './experiment-predefined-form.component.html',
  styleUrls: ['./experiment-predefined-form.component.scss'],
})
export class ExperimentPredefinedFormComponent implements OnInit, OnDestroy {
  /* states that are bond to html template */
  paramList: { name: string; required: string }[];

  /* inner states */
  templates: TemplateTable = {};
  predefinedForm: FormGroup;
  subs: Subscription[] = [];

  constructor(
    private experimentService: ExperimentService,
    private experimentFormService: ExperimentFormService,
    private fb: FormBuilder,
    private nzMessageService: NzMessageService
  ) {}

  ngOnInit() {
    this.experimentService.fetchExperimentTemplateList().subscribe((res) => {
      this.templates = this.parseTemplateRespond(res);

      if (Object.keys(this.templates).length != 0) {
        // default: switch to first template
        const defaultTemplate = Object.keys(this.templates)[0];
        this.predefinedForm.get('templateName').setValue(defaultTemplate);
        this.onTemplateChange();
      }
    });

    this.predefinedForm = this.fb.group({
      templateName: [null],
      params: this.fb.group({}),
    });

    this.experimentFormService.modalPropsChange({
      okText: 'Submit',
    });

    this.predefinedForm.statusChanges.subscribe((status) => {
      this.experimentFormService.btnStatusChange(status === 'INVALID');
    });

    const sub = this.experimentFormService.stepService.subscribe((step) => {
      // handle submit
      this.onSubmit();
    });

    this.subs.push(sub);
  }
  ngOnDestroy() {
    this.subs.forEach((sub) => sub.unsubscribe());
  }
  onSubmit() {
    // construct spec
    const finalSpec: ExperimentTemplateSubmit = {
      params: this.predefinedForm.get('params').value,
    };
    const templateName = this.predefinedForm.get('templateName').value;

    // send http post request
    this.experimentService.createExperimentfromTemplate(finalSpec, templateName).subscribe({
      next: () => {},
      error: (msg) => {
        this.nzMessageService.error(`${msg}, please try again`, {
          nzPauseOnHover: true,
        });
      },
      complete: () => {
        this.nzMessageService.success('Experiment creation succeeds');
        this.experimentFormService.fetchList();
        this.experimentFormService.modalPropsClear();
        this.predefinedForm.reset();
      },
    });
  }
  parseTemplateRespond(res: ExperimentTemplate[]): TemplateTable {
    let templates: TemplateTable = {};
    for (let item of res) {
      // iterate template list
      let template: ParsedTemplate = {
        templateParams: item.experimentTemplateSpec.parameters.filter((item) => !item.name.startsWith('spec.')),
        experimentName: item.experimentTemplateSpec.experimentSpec.meta.name,
        experimentNamespace: item.experimentTemplateSpec.experimentSpec.meta.namespace,
        experimentCommand: item.experimentTemplateSpec.experimentSpec.meta.cmd,
        experimentImage: item.experimentTemplateSpec.experimentSpec.environment.image,
        experimentVars: JSON.stringify(item.experimentTemplateSpec.experimentSpec.meta.envVars),
      };
      templates[item.experimentTemplateSpec.name] = template;
    }
    return templates;
  }

  onTemplateChange() {
    if (this.currentOption == null) return;
    /* update paramList */
    let tmpList = [];
    for (let item of this.templates[this.currentOption].templateParams)
      tmpList.push({ name: item.name, required: item.required });
    this.paramList = tmpList;

    let controls = {};
    for (let item of this.templates[this.currentOption].templateParams) {
      controls[item.name] = [item.value];
      if (item.required === 'true') controls[item.name].push([Validators.required]);
    }
    const new_param_group = this.fb.group(controls);
    this.predefinedForm.setControl('params', new_param_group);
  }

  /* sugar syntax for option */
  get currentOption(): string {
    return this.predefinedForm.get('templateName').value;
  }
  get optionList(): string[] {
    return Object.keys(this.templates);
  }
}
