import { IInstanceModel } from '@fleio-api/openstack/model/instance.model';
import { IPermissionsModel } from '@fleio-api/base-model/IPermissionsModel';
import { IIcon } from '@shared/ui/common/interfaces/icon';
import { ITitle } from '@objects-view/interfaces/card-data/card-title';
import { IObjectStatus, StatusType, StatusValue } from '@objects-view/interfaces/object-status';
import { ObjectUIServiceBase } from '@objects-view/object-ui-service-base';
import { IAction } from '@objects-view/interfaces/actions/action';
import { RouterLinkAction } from '@objects-view/actions/router-link-action';
import { Router } from '@angular/router';
import { ConfigService } from '@shared/config/config.service';
import { IDataField } from '@objects-view/interfaces/card-data/data-field';
import { InstancesApiService } from '@fleio-api/openstack/instance/instances-api.service';
import { ApiCallAction } from '@objects-view/actions/api-call-action';
import { IDetailsTab } from '@objects-view/interfaces/details/details-tab';
import { CallbackAction } from '@objects-view/actions/callback-action';
import { catchError, map } from 'rxjs/operators';
import { IActionResult } from '@objects-view/interfaces/actions/action-result';
import { MatDialog } from '@angular/material/dialog';
import { of } from 'rxjs';
import { DateFormatterPipe } from '@shared/ui/common/pipes/date-formatter.pipe';
import {
  InstanceRenameDialogComponent
} from '@openstack-instances-dialogs/instance-rename-dialog/instance-rename-dialog.component';
import {
  InstanceChangePasswordDialogComponent
} from '@openstack-instances-dialogs/instance-change-password-dialog/instance-change-password-dialog.component';
import {
  InstanceDetailsSystemLogComponent
} from '@openstack-instances-tabs/instance-details-system-log/instance-details-system-log.component';
import {
  InstanceDetailsMetricsComponent
} from '@openstack-instances-tabs/instance-details-metrics/instance-details-metrics.component';
import {
  InstanceDetailsSnapshotsComponent
} from '@openstack-instances-tabs/instance-details-snapshots/instance-details-snapshots.component';
import {
  InstanceDetailsVolumesComponent
} from '@openstack-instances-tabs/instance-details-volumes/instance-details-volumes.component';
import {
  InstanceDetailsNetworkingComponent
} from '@openstack-instances-tabs/instance-details-networking/instance-details-networking.component';
import {
  InstanceCreateFormComponent
} from '@openstack-instances-tabs/instance-create-form/instance-create-form.component';
import {
  InstanceResizeFormComponent
} from '@openstack-instances-tabs/instance-resize-form/instance-resize-form.component';
import {
  InstanceRescueFormComponent
} from '@openstack-instances-tabs/instance-rescue-form/instance-rescue-form.component';
import {
  InstanceRebuildFormComponent
} from '@shared/common-tabs/openstack/instances/instance-rebuild-form/instance-rebuild-form.component';
import {
  InstanceDetailsSecurityGroupsComponent
} from '@shared/common-tabs/openstack/instances/instance-details-security-groups/instance-details-security-groups.component';
import {
  InstanceDetailsBackupsComponent
} from '@shared/common-tabs/openstack/instances/instance-details-backups/instance-details-backups.component';
import {
  InstanceDeleteDialogComponent
} from '@openstack-instances-dialogs/instance-delete-dialog/instance-delete-dialog.component';
import {
  EnduserInstanceDetailsInfoComponent
} from './tabs/enduser-instance-details-info/enduser-instance-details-info.component';
import {
  EnduserInstanceDetailsHistoryLogComponent
} from './tabs/enduser-instance-details-history-log/enduser-instance-details-history-log.component';
import {
  InstanceDetailsAssociateIpDialogComponent
} from '@openstack-instances-dialogs/instance-details-associate-ip-dialog/instance-details-associate-ip-dialog.component';
import {
  InstanceDissociateIpDialogComponent
} from '@openstack-instances-dialogs/instance-dissociate-ip-dialog/instance-dissociate-ip-dialog.component';
import {
  InstanceDetailsTrafficComponent
} from '@openstack-instances-tabs/instance-details-traffic/instance-details-traffic.component';
import {
  InstanceUnshelveDialogComponent
} from '@openstack-instances-dialogs/instance-unshelve-dialog/instance-unshelve-dialog.component';
import { NotificationService } from '@shared/ui-api/notification.service';

export class InstanceUIService extends ObjectUIServiceBase<IInstanceModel> {
  private statusMap: Map<string, IObjectStatus> = new Map<string, IObjectStatus>([

    ['active', {type: StatusType.Defined, value: StatusValue.Active}],
    ['paused', {type: StatusType.Defined, value: StatusValue.Paused}],
    ['suspended', {type: StatusType.Defined, value: StatusValue.Paused}],
    ['building', {type: StatusType.Changing, value: StatusValue.Waiting}],

    ['rescued', {type: StatusType.Defined, value: StatusValue.Rescued}],
    ['booted_from_iso', {type: StatusType.Defined, value: StatusValue.Rescued}],
    ['resized', {type: StatusType.Defined, value: StatusValue.Resized}],

    ['stopped', {type: StatusType.Defined, value: StatusValue.Stopped}],
    ['shelved_offloaded', {type: StatusType.Defined, value: StatusValue.Stopped}],

    ['deleted', {type: StatusType.Defined, value: StatusValue.Deleted}],
    ['error', {type: StatusType.Defined, value: StatusValue.Error}],
  ]);

  availableDistroLogos = [
    'centos', 'coreos', 'debian', 'fedora', 'freebsd', 'ubuntu', 'windows', 'arch', 'cirros', 'gnome', 'macos',
    'mageia', 'netbsd', 'opensuse', 'rhel', 'netware', 'solaris', 'almalinux', 'rockylinux',
  ];

  private isVolumeBooted() {
    if (this.object) {
      if (this.object.storage_details) {
        if (this.object.storage_details.volume_attachments && this.object.storage_details.volume_attachments.length) {
          for (const volAtt of this.object.storage_details.volume_attachments) {
            if (volAtt.is_boot === true) {
              return true;
            }
          }
        }
      }
    }
    return false;
  }


  constructor(
    instance: IInstanceModel, permissions: IPermissionsModel, state: string,
    private router: Router,
    private config: ConfigService,
    private instancesApi: InstancesApiService,
    private matDialog: MatDialog,
    private notificationService: NotificationService,
  ) {
    super(instance, permissions, state);
  }

  getIcon(): IIcon {
    if (this.state === 'create') {
      return null;
    }
    let iconName = 'otheros';
    if (this.object && this.object.image) {
      if (this.object.image.os_distro) {
        const distro = this.object.image.os_distro.split('-').pop();
        if (this.availableDistroLogos.indexOf(distro) > -1) {
          iconName = distro;
        }
      }
    }

    return {
      name: iconName,
      class: 'fl-icons',
    };
  }


  getStatus(): IObjectStatus {
    if (this.object.display_task) {
      switch (this.object.display_task) {
        case 'powering-on':
          return {type: StatusType.Changing, value: StatusValue.Waiting};
        case 'powering-off':
          return {type: StatusType.Changing, value: StatusValue.Waiting};
        case 'spawning':
          return {type: StatusType.Changing, value: StatusValue.Waiting};
        default:
          return {type: StatusType.Changing, value: StatusValue.Waiting};
      }
    }

    let status: IObjectStatus = {type: StatusType.None, value: StatusValue.None};
    if (this.statusMap.has(this.object.status)) {
      status = this.statusMap.get(this.object.status);
    }
    return status;
  }

  getTitle(): ITitle {
    let subText = this.object.display_status?.toLocaleUpperCase();
    if (this.object.display_task) {
      subText = `${subText} (${this.object.display_task})`;
    }
    let subTextIcon = null as IIcon;
    let subTextIconTooltip = null;
    if (this.object.status === 'resized') {
      subTextIcon = {
        name: 'warning'
      };
      subTextIconTooltip = $localize`Check if files have been successfully\nmigrated to the
      new instance disk. \nChoose Confirm resize from the instance menu\nto confirm migration was successful,
      otherwise\nchoose Revert resize to revert back to the initial disk.`;
      if (this.config.current.settings.openstack.instances.verifyResizeExtraMessage) {
        subTextIconTooltip +=
          $localize`:@@VERIFY.RESIZE.EXTRA.MSG: ${this.config.current.settings.openstack.instances.verifyResizeExtraMessage}`;
      }
    }
    switch (this.state) {
      case 'details':
        return {
          text: `${this.object.name}`,
          subText,
          subTextIcon,
          subTextIconTooltip
        };

      case 'rescue':
        return {
          text: $localize`Rescue ${this.object.name}`,
          subText,
        };

      case 'create':
        return {
          text: $localize`Create instance`,
        };

      default:
        return {
          text: `${this.object.name}`,
          subText,
          subTextIcon,
          subTextIconTooltip
        };
    }
  }

  getActions(): IAction[] {
    const actions: IAction[] = [];

    const rebootRadioButtons = [
      {
        selected: true,
        id: 'soft_reboot',
        message: $localize`Soft reboot`,
      },
      {
        selected: false,
        id: 'hard_reboot',
        message: $localize`Hard reboot`,
      }
    ];

    for (const actionName of this.object.allowed_actions) {
      switch (actionName) {
        case 'start':
          actions.push(new ApiCallAction(
            {
              object: this.object,
              icon: {name: 'power', class: 'fl-icons'},
              name: $localize`Start`,
              tooltip: $localize`Start instance`,
              apiService: this.instancesApi,
              apiAction: 'start',
              disabled: !!this.object.display_task,
              noPermissions: !this.permissions['instances.start'],
            }
          ));
          break;
        case 'shutoff':
          actions.push(new ApiCallAction(
            {
              object: this.object,
              icon: {name: 'power', class: 'fl-icons'},
              name: $localize`Shut down`,
              tooltip: $localize`Shut down`,
              confirmOptions: {
                confirm: true,
                title: $localize`Stop instance`,
                message: $localize`Are you sure you want to stop instance ${this.object.name}?`,
                importantMessage: this.config.current.settings.openstack.instances.shutDownInstanceNote || null
              },
              apiService: this.instancesApi,
              noPermissions: !this.permissions['instances.stop'],
              apiAction: 'stop',
              disabled: !!this.object.display_task
            }
          ));
          break;
        case 'reboot':
          actions.push(new CallbackAction(
            {
              object: this.object,
              icon: {name: 'reboot', class: 'fl-icons'},
              name: $localize`Reboot`,
              tooltip: $localize`Reboot`,
              redirectAfterExecute: false,
              refreshAfterExecute: true,
              displayMessages: true,
              confirmOptions: {
                confirm: true,
                title: $localize`Reboot instance`,
                message: $localize`Are you sure you want to reboot instance ${this.object.name}?`,
                yesButtonName: $localize`Reboot`,
                noButtonName: $localize`Cancel`,
                radioButtons: rebootRadioButtons,
              },
              disabled: !!this.object.display_task,
              noPermissions: !this.permissions['instances.reboot'],
              callback: (action, result) => {
                if (result?.button === 'yes') {
                  const hardReboot = !!result.flags?.hard_reboot;
                  return this.instancesApi.reboot(this.object.id, {
                    reboot_type: hardReboot ? 'HARD' : 'SOFT',
                  }).pipe(map(response => {
                    return {
                      success: true,
                      message: response.detail,
                    } as IActionResult;
                  }), catchError((error, caught) => {
                    return of({success: false, message: error.error.detail} as IActionResult)
                  }));
                } else {
                  return of({success: false} as IActionResult);
                }
              }
            }
          ));
          break;
        case 'shelve':
          actions.push(new ApiCallAction(
            {
              object: this.object,
              icon: {name: 'archive'},
              name: $localize`Shelve`,
              tooltip: $localize`Shelve`,
              confirmOptions: {
                confirm: true,
                title: $localize`Shelve instance`,
                message: $localize`Are you sure you want to shelve instance ${this.object.name}?`
              },
              apiService: this.instancesApi,
              apiAction: 'shelve',
              disabled: !!this.object.display_task,
              noPermissions: !this.permissions['instances.shelve'],
              featureName: 'openstack.instances.shelving',
            }
          ));
          break;
        case 'unshelve':
          actions.push(new CallbackAction(
            {
              object: this.object,
              icon: {name: 'unarchive'},
              name: $localize`Unshelve`,
              tooltip: $localize`Unshelve`,
              disabled: !!this.object.display_task,
              callback: () => this.matDialog.open(
                InstanceUnshelveDialogComponent, {
                  data: {instance: this.object},
                  autoFocus: false,
                }).afterClosed().pipe(map(result => ({message: result} as IActionResult))),
              noPermissions: !this.permissions['instances.unshelve'],
              featureName: 'openstack.instances.shelving',
            }
          ));
          break;
        case 'reset_state':
          const resetStateAction = new ApiCallAction(
            {
              object: this.object,
              icon: {name: 'redo'},
              name: $localize`Reset state`,
              tooltip: $localize`Reset state`,
              confirmOptions: {
                confirm: true,
                title: $localize`Reset instance state`,
                message: $localize`Are you sure you want to reset instance ${this.object.name} state?`
              },
              apiService: this.instancesApi,
              apiAction: 'reset_state',
              noPermissions: !this.permissions['instances.reset-state'],
            }
          );
          if (!this.object.host_name || !this.object.hostId) {
            resetStateAction.disabled = true;
            resetStateAction.tooltip = $localize`You cannot reset state on an instance without hypervisor!`;
          }
          actions.push(resetStateAction);
          break;
        case 'unrescue':
          actions.push(new ApiCallAction(
            {
              object: this.object,
              icon: {name: 'build'},
              name: $localize`Unrescue`,
              tooltip: $localize`Unrescue`,
              confirmOptions: {
                confirm: true,
                title: $localize`Unrescue instance`,
                message: $localize`Are you sure you want to unrescue instance ${this.object.name}?`
              },
              apiService: this.instancesApi,
              apiAction: 'unrescue',
              noPermissions: !this.permissions['instances.unrescue'],
            }
          ));
          break;
        case 'unmount_and_reboot':
          actions.push(new ApiCallAction(
            {
              object: this.object,
              icon: {name: 'build'},
              name: $localize`Unmount ISO and reboot`,
              tooltip: $localize`Unmount ISO and reboot`,
              confirmOptions: {
                confirm: true,
                title: $localize`Unmount ISO and reboot`,
                message: $localize`Are you sure you want to unmount ISO and reboot?`
              },
              apiService: this.instancesApi,
              apiAction: 'unrescue',
              noPermissions: !this.permissions['instances.unrescue'],
            }
          ));
          break;
        case 'cfresize':
          actions.push(new ApiCallAction(
            {
              object: this.object,
              icon: {name: 'check'},
              name: $localize`Confirm resize`,
              tooltip: $localize`Confirm resize`,
              confirmOptions: {
                confirm: true,
                title: $localize`Confirm instance resize`,
                message: $localize`Are you sure you want to confirm instance ${this.object.name} resize?`
              },
              apiService: this.instancesApi,
              apiAction: 'confirm_resize',
              noPermissions: !this.permissions['instances.confirm-resize'],
            }
          ));
          actions.push(new ApiCallAction(
            {
              object: this.object,
              icon: {name: 'cancel'},
              name: $localize`Revert resize`,
              tooltip: $localize`Revert resize`,
              confirmOptions: {
                confirm: true,
                title: $localize`Revert instance resize`,
                message: $localize`Are you sure you want to revert instance ${this.object.name} resize?`
              },
              apiService: this.instancesApi,
              apiAction: 'revert_resize',
              noPermissions: !this.permissions['instances.revert-resize'],
            }
          ));
          break;
        case 'rescue':
          actions.push(new RouterLinkAction({
              icon: {name: 'help', class: 'fl-icons'},
              name: $localize`Rescue`,
              tooltip: $localize`Rescue`,
              routerUrl: this.config.getPanelUrl(`openstack/instances/${this.object.id}/rescue`),
              router: this.router,
              noPermissions: !this.permissions['instances.rescue'],
            }
          ));
          break;
        case 'boot_from_iso':
          actions.push(new RouterLinkAction({
              icon: {name: 'help', class: 'fl-icons'},
              name: $localize`Boot from ISO`,
              tooltip: $localize`Boot from ISO`,
              routerUrl: this.config.getPanelUrl(`openstack/instances/${this.object.id}/boot-from-iso`),
              router: this.router,
              noPermissions: !this.permissions['instances.boot_from_iso'],
            }
          ));
          break;
        case 'resize':
          actions.push(new RouterLinkAction({
              icon: {name: 'resize', class: 'fl-icons'},
              name: $localize`Resize`,
              tooltip: $localize`Resize`,
              routerUrl: this.config.getPanelUrl(`openstack/instances/${this.object.id}/resize`),
              router: this.router,
              noPermissions: !this.permissions['instances.resize'],
            }
          ));
          break;
        case 'rebuild':
          actions.push(new RouterLinkAction({
              icon: {name: 'rebuild', class: 'fl-icons'},
              name: $localize`Rebuild`,
              tooltip: $localize`Rebuild`,
              routerUrl: this.config.getPanelUrl(`openstack/instances/${this.object.id}/rebuild`),
              router: this.router,
              noPermissions: !this.permissions['instances.rebuild'],
            }
          ));
          break;
        case 'rename':
          actions.push(new CallbackAction(
            {
              object: this.object,
              icon: {name: 'edit', class: 'fl-icon'},
              tooltip: $localize`Rename`,
              name: $localize`Rename`,
              refreshAfterExecute: true,
              noPermissions: !this.permissions['instances.rename'],
              callback: () => this.matDialog.open(
                InstanceRenameDialogComponent, {
                  data: {instance: this.object},
                  autoFocus: false,
                }).afterClosed().pipe(map(result => ({message: result} as IActionResult)))
            }
          ));
          break;
        case 'change_password':
          actions.push(new CallbackAction(
            {
              object: this.object,
              icon: {name: 'security'},
              tooltip: $localize`Change password`,
              name: $localize`Change password`,
              noPermissions: !this.permissions['instances.change-password'],
              callback: () => this.matDialog.open(
                InstanceChangePasswordDialogComponent, {
                  data: {instance: this.object},
                  autoFocus: false,
                }).afterClosed().pipe(map(result => ({message: result} as IActionResult))),
              disabled: !!this.object.display_task
            }
          ));
          break;
        case 'associate_ip':
          actions.push(new CallbackAction(
            {
              object: this.object,
              icon: {name: 'add'},
              tooltip: $localize`Assign floating IP`,
              name: $localize`Assign floating IP`,
              noPermissions: !this.permissions['instances.add_floating_ip'],
              callback: () => {
                this.instancesApi.getAssociateIpCreateOptions(this.object.id).subscribe({
                  next: response => {
                    this.matDialog.open(
                      InstanceDetailsAssociateIpDialogComponent, {
                        data: {
                          instance: this.object,
                          ports: response.ports,
                          freeIps: response.free_ips
                        },
                        autoFocus: false,
                      }).afterClosed().subscribe((value) => {
                      if (value) {
                        this.notificationService.showMessage($localize`Ip is being associated.`);
                      }
                    });
                  }
                });
                return of(null);
              },
              disabled: !!this.object.display_task
            }
          ));
          break;
        case 'dissociate_ip':
          actions.push(new CallbackAction(
            {
              object: this.object,
              icon: {name: 'remove'},
              tooltip: $localize`Dissociate IP`,
              name: $localize`Dissociate IP`,
              noPermissions: !this.permissions['instances.remove_floating_ip'],
              callback: () => {
                this.instancesApi.getDissociateIpOptions(this.object.id).subscribe({
                  next: response => {
                    this.matDialog.open(
                      InstanceDissociateIpDialogComponent, {
                        data: {
                          instance: this.object,
                          ips: response.ips,
                        },
                        autoFocus: false,
                      }).afterClosed().subscribe((value) => {
                      if (value) {
                        this.notificationService.showMessage($localize`Floating ip dissociated`);
                      }
                    });
                  },
                  error: error => {
                    if (error?.error?.detail) {
                      this.notificationService.showMessage(error.error.detail);
                    } else {
                      this.notificationService.showMessage($localize`Cannot get IPs`);
                    }
                  }
                });
                return of(null);
              },
              disabled: !!this.object.display_task
            }
          ));
          break;
        case 'console':
          actions.push(new CallbackAction(
            {
              object: this.object,
              icon: {name: 'code', class: 'fl-tooltip'},
              tooltip: $localize`Console`,
              name: $localize`Console`,
              callback: () => {
                const consoleWindow = window.open(
                  '',
                  this.object.id as string,
                  'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no'
                );
                return this.instancesApi.getConsoleUrl(this.object.id).pipe(map(result => {
                  consoleWindow.focus();
                  if (result.lxc) {
                    consoleWindow.location = result.url;
                  } else if (result.remote_console) {
                    consoleWindow.location = result.remote_console.url;
                  } else {
                    result.consoleWindow.location = result.console.url;
                  }
                  return {message: result} as IActionResult;
                }), catchError(() => {
                  consoleWindow.close();
                  return of(null);
                }));
              },
              disabled: !!this.object.display_task
            }
          ));
          break;
      }
    }

    actions.push(new CallbackAction(
      {
        object: this.object,
        icon: {name: 'delete'},
        tooltip: $localize`Delete`,
        name: $localize`Delete`,
        noPermissions: !this.permissions['instances.destroy'],
        callback: () => this.matDialog.open(
          InstanceDeleteDialogComponent, {
            data: {instance: this.object},
            autoFocus: false,
          }).afterClosed().pipe(map(result => ({message: result} as IActionResult))),
      }
    ));
    return actions;
  }

  getCardTags(): string[] {
    const tags: string[] = [];
    if (this.object.locked) {
      tags.push($localize`locked`);
    }
    return tags;
  }

  getDetailsLink(): string {
    return this.config.getPanelUrl(`openstack/instances/${this.object.id}`);
  }

  getCardFields(): IDataField[] {
    const datePipe = new DateFormatterPipe(this.config);
    let regionField = this.object.region;
    if (this.config.authService.feature('openstack.instances.show_hypervisors') &&
      (this.object.host_name || this.object.hostId)) {
      regionField += `, ${this.object.host_name || this.object.hostId}`;
    }


    const accessIp = this.object.access_ip ? this.object.access_ip : $localize`no IP`;

    const fields: Array<IDataField> = [
      {
        value: this.object.flavor ? `${accessIp}, ${this.object.flavor.name}` : `${accessIp}`
      },
      {
        name: $localize`Region`,
        value: regionField
      },
    ];

    const showAZ = this.config.authService.feature('openstack.instances.availability_zones');
    if (showAZ) {
      fields.push({
        name: $localize`Availability zone`,
        value: this.object.availability_zone || $localize`n/a`
      });
    }

    // do not show creation date if it doesn't fit due to other more important fields
    const hasTags = this.getCardTags().length > 0;
    const creationDateFits = !hasTags || !showAZ;
    if (creationDateFits) {
      fields.push({
          name: $localize`Created on`,
          value: `${datePipe.transform(this.object.created)}`,
          title: `${datePipe.getTitleAttributeValue(this.object.created)}`,
        }
      );
    }

    return fields;
  }

  getTabs(): IDetailsTab[] {
    switch (this.state) {
      case 'details':
        const tabs = [
          {
            tabName: $localize`Info`,
            tabIdentifier: 'info',
            component: EnduserInstanceDetailsInfoComponent,
          },
          {
            tabName: $localize`Networking`,
            tabIdentifier: 'networking',
            component: InstanceDetailsNetworkingComponent,
            featureName: 'openstack.instances.networking.edit'
          },
          {
            tabName: $localize`System log`,
            tabIdentifier: 'system-log',
            component: InstanceDetailsSystemLogComponent,
          },
          {
            tabName: $localize`Metrics`,
            tabIdentifier: 'metrics',
            component: InstanceDetailsMetricsComponent,
          },
          {
            tabName: $localize`Network traffic`,
            tabIdentifier: 'network-traffic',
            component: InstanceDetailsTrafficComponent,
            featureName: 'openstack.instances.traffic',
          },
        ] as Array<IDetailsTab>;
        if (this.config.authService.feature('openstack.instances.snapshots') &&
          this.object.region_obj.enable_snapshots) {
          tabs.push({
            tabName: $localize`Snapshots`,
            tabIdentifier: 'snapshots',
            component: InstanceDetailsSnapshotsComponent,
            featureName: 'openstack.instances.snapshots',
          });
        }
        if (this.config.authService.feature('openstack.volumes') &&
          this.object.region_obj.enable_volumes) {
          tabs.push({
            tabName: $localize`Volumes`,
            tabIdentifier: 'volumes',
            component: InstanceDetailsVolumesComponent,
            featureName: 'openstack.volumes',
          });
        }
        tabs.push.apply(tabs, [
          {
            tabName: $localize`History log`,
            tabIdentifier: 'history-log',
            component: EnduserInstanceDetailsHistoryLogComponent,
          },
          {
            tabName: $localize`Security groups`,
            tabIdentifier: 'security-groups',
            component: InstanceDetailsSecurityGroupsComponent,
            featureName: 'openstack.securitygroups',
          },
        ]);
        if (!this.isVolumeBooted()) {
          tabs.push({
            tabName: $localize`Backups`,
            tabIdentifier: 'backups',
            component: InstanceDetailsBackupsComponent,
            featureName: 'openstack.osbackup',
          });
        }
        return tabs;
      case 'create':
        return [
          {
            tabName: $localize`Create`,
            tabIdentifier: 'create',
            component: InstanceCreateFormComponent,
          },
        ];
      case 'resize':
        return [
          {
            tabName: $localize`Resize`,
            tabIdentifier: 'resize',
            component: InstanceResizeFormComponent
          }
        ];
      case 'rescue':
        return [
          {
            tabName: $localize`Rescue`,
            tabIdentifier: 'rescue',
            component: InstanceRescueFormComponent
          }
        ];
      case 'bootFromIso':
        return [
          {
            tabName: $localize`Boot from iso`,
            tabIdentifier: 'boot-from-iso',
            component: InstanceRescueFormComponent
          }
        ];
      case 'rebuild':
        return [
          {
            tabName: $localize`Rebuild`,
            tabIdentifier: 'rebuild',
            component: InstanceRebuildFormComponent
          }
        ];
    }
  }

  getDetailsActions(): IAction[] {
    const actions = [];
    switch (this.state) {
      case 'create':
        actions.push(new RouterLinkAction({
            name: $localize`Cancel`,
            routerUrl: this.config.getPrevUrl(`openstack/instances`),
            router: this.router,
          }
        ));
        actions.push(new CallbackAction({name: 'Create'}));
        break;
      case 'resize':
        actions.push(new RouterLinkAction({
            name: $localize`Cancel`,
            routerUrl: this.config.getPrevUrl(`openstack/instances`),
            router: this.router,
          }
        ));
        actions.push(new CallbackAction({name: 'Resize'}));
        break;
      case 'rescue':
        actions.push(new RouterLinkAction({
            name: $localize`Cancel`,
            routerUrl: this.config.getPrevUrl(`openstack/instances`),
            router: this.router,
          }
        ));
        actions.push(new CallbackAction({name: 'Rescue'}));
        break;
      case 'bootFromIso':
        actions.push(new RouterLinkAction({
            name: $localize`Cancel`,
            routerUrl: this.config.getPrevUrl(`openstack/instances`),
            router: this.router,
          }
        ));
        actions.push(new CallbackAction({name: 'Boot instance from ISO'}));
        break;
      case 'rebuild':
        actions.push(new RouterLinkAction({
            name: $localize`Cancel`,
            routerUrl: this.config.getPrevUrl(`openstack/instances`),
            router: this.router,
          }
        ));
        actions.push(new CallbackAction({name: $localize`Rebuild`}));
        break;
    }

    return actions;
  }

  getObjectDetailsRefreshInterval(): number {
    switch (this.state) {
      case 'details':
        return this.config.getDefaultRefreshInterval(true);
      default:
        return null;
    }
  }
}
