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 {
  InstanceMoveDialogComponent
} from '@openstack-instances-dialogs/instance-move-dialog/instance-move-dialog.component';
import {
  InstanceMigrateDialogComponent
} from '@openstack-instances-dialogs/instance-migrate-dialog/instance-migrate-dialog.component';
import {
  InstanceChangePasswordDialogComponent
} from '@openstack-instances-dialogs/instance-change-password-dialog/instance-change-password-dialog.component';
import {
  InstanceDetailsInfoComponent
} from '@openstack-instances-tabs/instance-details-info/instance-details-info.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 {
  InstanceDetailsHistoryLogComponent
} from '@openstack-instances-tabs/instance-details-history-log/instance-details-history-log.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 {
  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 { EntityAuditLogComponent } from '../../common-components/entity-audit-log/entity-audit-log.component';

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 readonly router: Router;
  private readonly config: ConfigService;
  private readonly instancesApi: InstancesApiService;
  private readonly matDialog: MatDialog;

  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,
    router: Router, config: ConfigService, instancesApi: InstancesApiService,
    matDialog: MatDialog,
  ) {
    super(instance, permissions, state);
    this.router = router;
    this.config = config;
    this.instancesApi = instancesApi;
    this.matDialog = matDialog;
  }

  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
      migrated to the new instance disk.
      Choose Confirm resize from the instance menu
      to confirm migration was successful, otherwise
      choose 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 'abort_migrate':
          if (this.object.display_task === 'migrating') {
            actions.push(new ApiCallAction(
              {
                object: this.object,
                icon: {name: 'redo'},
                name: $localize`Abort migrate`,
                tooltip: $localize`Abort migrate`,
                apiService: this.instancesApi,
                apiAction: 'abort_migrate',
                disabled: !!this.object.display_task,
                noPermissions: !this.permissions['instances.abort-migrate'],
              }
            ));
          }
          break;
        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 'suspend':
          actions.push(new ApiCallAction(
            {
              object: this.object,
              icon: {name: 'pause'},
              name: $localize`Suspend`,
              tooltip: $localize`Suspend`,
              confirmOptions: {
                confirm: true,
                title: $localize`Suspend instance`,
                message: $localize`Are you sure you want to suspend instance ${this.object.name}?`
              },
              apiService: this.instancesApi,
              apiAction: 'suspend',
              disabled: !!this.object.display_task,
              noPermissions: !this.permissions['instances.suspend'],
            }
          ));
          break;
        case 'resume':
          actions.push(new ApiCallAction(
            {
              object: this.object,
              icon: {name: 'play_arrow'},
              name: $localize`Resume`,
              tooltip: $localize`Resume`,
              confirmOptions: {
                confirm: false,
                title: $localize`Resume instance`,
                message: $localize`Are you sure you want to resume instance ${this.object.name}?`
              },
              apiService: this.instancesApi,
              apiAction: 'resume',
              disabled: !!this.object.display_task,
              noPermissions: !this.permissions['instances.resume'],
            }
          ));
          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 '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.confirmOptions.importantMessage = $localize`Resetting state on an instance without hypervisor may cause Fleio to malfunction.\n If this happens you need to delete the instance from OpenStack.`;
          }
          actions.push(resetStateAction);
          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 'lock':
          actions.push(new ApiCallAction(
            {
              object: this.object,
              icon: {name: 'lock'},
              name: $localize`Lock`,
              tooltip: $localize`Lock`,
              confirmOptions: {
                confirm: true,
                title: $localize`Lock instance`,
                message: $localize`Are you sure you want to lock instance ${this.object.name}?`
              },
              apiService: this.instancesApi,
              apiAction: 'lock',
              disabled: !!this.object.display_task,
              noPermissions: !this.permissions['instances.lock'],
            }
          ));
          break;
        case 'unlock':
          actions.push(new ApiCallAction(
            {
              object: this.object,
              icon: {name: 'lock_open'},
              name: $localize`Unlock`,
              tooltip: $localize`Unlock`,
              confirmOptions: {
                confirm: true,
                title: $localize`Unlock instance`,
                message: $localize`Are you sure you want to unlock instance ${this.object.name}?`
              },
              apiService: this.instancesApi,
              apiAction: 'unlock',
              disabled: !!this.object.display_task,
              noPermissions: !this.permissions['instances.unlock'],
            }
          ));
          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 'move':
          actions.push(new CallbackAction(
            {
              object: this.object,
              icon: {name: 'trending_flat'},
              tooltip: $localize`Move`,
              name: $localize`Move`,
              noPermissions: !this.permissions['instances.move'],
              callback: () => this.matDialog.open(
                InstanceMoveDialogComponent, {
                  data: {instance: this.object},
                  autoFocus: false,
                }).afterClosed().pipe(map(result => ({message: result} as IActionResult))),
              disabled: !!this.object.display_task
            }
          ));
          break;
        case 'migrate':
          actions.push(new CallbackAction(
            {
              object: this.object,
              icon: {name: 'trending_flat'},
              tooltip: $localize`Migrate`,
              name: $localize`Migrate`,
              noPermissions: !this.permissions['instances.migrate'],
              callback: () => this.matDialog.open(
                InstanceMigrateDialogComponent, {
                  data: {instance: this.object},
                  autoFocus: false,
                }).afterClosed().pipe(map(result => ({message: result} as IActionResult))),
              disabled: !!this.object.display_task
            }
          ));
          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 '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);
    const accessIp = this.object.access_ip ? this.object.access_ip : $localize`no IP`;

    return [
      {
        value: this.object.flavor ?
          `${accessIp}, ${this.object.flavor.name}, ${this.object.region}` :
          `${accessIp}, ${this.object.region}`
      },
      {
        name: $localize`Created on`,
        value: `${datePipe.transform(this.object.created)}`,
        title: `${datePipe.getTitleAttributeValue(this.object.created)}`
      },
      {
        name: $localize`Client`,
        value: this.object.client ? this.object.client.display : $localize`n/a`,
      }
    ];
  }

  getTabs():
    IDetailsTab[] {
    switch (this.state) {
      case 'details':
        const tabs = [
          {
            tabName: $localize`Info`,
            tabIdentifier: 'info',
            component: InstanceDetailsInfoComponent,
          },
          {
            tabName: $localize`Networking`,
            tabIdentifier: 'networking',
            component: InstanceDetailsNetworkingComponent,
          },
          {
            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>;
        tabs.push({
          tabName: $localize`Snapshots`,
          tabIdentifier: 'snapshots',
          component: InstanceDetailsSnapshotsComponent,
          featureName: 'openstack.instances.snapshots',
        });
        if (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: InstanceDetailsHistoryLogComponent,
          },
          {
            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',
          });
        }
        tabs.push({
          tabName: $localize`Audit log`,
          tabIdentifier: 'audit-log',
          component: EntityAuditLogComponent,
          featureName: 'utils.activitylog',
          data: {
            entity_type: 'instance'
          }
        })
        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: $localize`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: $localize`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: $localize`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: $localize`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;
    }
  }
}
