//  Copyright (c) 2024 Huawei Technologies Co., Ltd.
//  openUBMC is licensed under Mulan PSL v2.
//  You can use this software according to the terms and conditions of the Mulan PSL v2.
//  You may obtain a copy of Mulan PSL v2 at:
//        #  http://license.coscl.org.cn/MulanPSL2
//  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
//  EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
//  MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
//  See the Mulan PSL v2 for more details.

import { getStoreData, setStoreData } from '@/utils/composition';
import { getGenericInfo } from '@/services/header/header.service';
import { RouterChangeReason } from '@/model/base-enum';
import { getRandomNumber } from '@/utils/utils';
import type { LocationQuery, RouteLocationNormalized } from 'vue-router';

/**
 * SystemIds 工具函数
 *
 * 提供systemId相关的公共逻辑,包括:
 * 1. 获取有效的SystemIds数据
 * 2. 验证systemId参数的有效性
 * 3. 生成修正后的查询参数
 * 4. 判断是否为多主机环境
 */

/**
 * 获取有效的SystemIds数据
 *
 * 优先使用store中的数据,如果没有则通过API获取
 * 用于验证路由参数和配置多主机环境
 *
 * @returns Promise<number[]> - 返回有效的SystemIds数组
 */
export async function getValidSystemIds(): Promise<number[]> {
  // 优先使用store中的数据
  const storeSystemIds = getStoreData('loct', 'systemIds');
  if (Array.isArray(storeSystemIds) && storeSystemIds.length > 0) {
    return storeSystemIds;
  }

  try {
    // 从API获取数据
    let apiSystemIds: number[] = [];
    const res = await getGenericInfo();
    apiSystemIds = res.SystemIds || [];

    // 将获取到的数据存储到store中,避免重复请求
    if (apiSystemIds.length > 0) {
      setStoreData('loct', 'systemIds', apiSystemIds);
    }

    return apiSystemIds;
  } catch (error) {
    // 出错时返回空数组,按单主机处理
    return [];
  }
}

/**
 * 验证systemId参数并生成修正后的查询参数
 *
 * 根据SystemIds数据验证当前查询参数中的systemId是否有效
 * 并返回修正后的查询参数对象
 *
 * @param currentQuery - 当前查询参数
 * @param systemIds - 有效的SystemIds数组
 * @returns 修正后的查询参数对象
 */
export function validateSystemIdQuery(
  currentQuery: LocationQuery,
  systemIds: number[]
): LocationQuery {
  // 双主机环境
  if (systemIds.length === 2) {
    const routeSystemId = currentQuery.systemId;

    // 验证路由参数中的systemId是否有效
    if (routeSystemId && systemIds.includes(Number(routeSystemId))) {
      // systemId参数有效,返回原参数
      return { ...currentQuery };
    } else {
      // systemId参数无效或缺失,默认使用第一个系统ID
      const defaultSystemId = systemIds[0];
      return {
        ...currentQuery,
        systemId: `${defaultSystemId}`
      };
    }
  } else {
    // 单主机环境或空数据,清理路由中可能存在的多余systemId参数
    if (currentQuery.systemId) {
      const { systemId, ...cleanQuery } = currentQuery;
      return cleanQuery;
    } else {
      // 正常返回原参数
      return { ...currentQuery };
    }
  }
}

/**
 * 获取当前有效的systemId值
 *
 * 根据SystemIds数据和当前查询参数,返回应该使用的systemId值
 *
 * @param currentQuery - 当前查询参数
 * @param systemIds - 有效的SystemIds数组
 * @returns 返回应该使用的systemId值(字符串),如果是单主机则返回null
 */
export function getCurrentSystemId(currentQuery: LocationQuery, systemIds: number[]): string {
  if (systemIds.length === 2) {
    // 双主机环境
    const routeSystemId = currentQuery.systemId;

    if (routeSystemId && systemIds.includes(Number(routeSystemId))) {
      return String(routeSystemId);
    } else {
      // 使用默认值
      return String(systemIds[0]);
    }
  } else {
    // 单主机环境,默认返回1
    return '1';
  }
}

/**
 * 判断是否为多主机环境
 *
 * @param systemIds - SystemIds数组
 * @returns true表示多主机环境(双主机),false表示单主机环境
 */
export function isMultiHostEnvironment(systemIds: number[]): boolean {
  return systemIds.length === 2;
}

/**
 * 触发路由错误事件
 *
 * 用于处理systemId验证失败等场景
 */
export function triggerRouteError(): void {
  setStoreData('event', 'routeChangeError', RouterChangeReason.invalid + getRandomNumber());
}

/**
 * SystemIds验证结果类型
 */
export interface SystemIdsValidationResult {
  /** 是否为多主机环境 */
  isMultiHost: boolean;
  /** 当前应该使用的systemId值(双主机环境) */
  currentSystemId: string | null;
  /** 修正后的查询参数 */
  validatedQuery: LocationQuery;
  /** 有效的SystemIds数组 */
  validSystemIds: number[];
}

/**
 * 完整的SystemIds验证和查询参数修正
 *
 * 整合所有验证逻辑,提供一站式的systemId验证服务
 *
 * @param route - 当前路由对象
 * @returns Promise<SystemIdsValidationResult> - 验证结果
 */
export async function validateSystemIds(
  route: RouteLocationNormalized
): Promise<SystemIdsValidationResult> {
  // 获取有效的SystemIds数据
  const validSystemIds = await getValidSystemIds();

  // 验证查询参数
  const validatedQuery = validateSystemIdQuery(route.query, validSystemIds);

  // 获取当前systemId
  const currentSystemId = getCurrentSystemId(route.query, validSystemIds);

  // 判断环境类型
  const isMultiHost = isMultiHostEnvironment(validSystemIds);

  return {
    isMultiHost,
    currentSystemId,
    validatedQuery,
    validSystemIds
  };
}