//  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 { RouterChangeReason } from '@/model/base-enum';
import { getStoreData, setStoreData } from '@/utils/composition';
import { NavigationGuardNext, RouteLocationNormalized } from 'vue-router';
import { getRandomNumber } from '@/utils/utils';
import { getGenericInfo } from '@/services/header/header.service';

/**
 * 创建通用的功能支持路由守卫
 * 用于验证环境是否支持该功能，防止不支持该功能的环境通过路由跳转进入页面
 * @param storeKey loct store 中的支持标志键名
 * @returns 路由守卫函数
 */
export function createSupportGuard(storeKey: string) {
  return function (
    to: RouteLocationNormalized,
    from: RouteLocationNormalized,
    next: NavigationGuardNext,
  ): void {
    const supported = getStoreData('loct', storeKey);
    if (supported === null) {
      // 数据未就绪，调用接口兜底
      getGenericInfo().then(res => {
        if ((res as any)[storeKey] === false) {
          setStoreData('event', 'routeChangeError', RouterChangeReason.invalid + getRandomNumber());
        } else {
          next();
        }
      });
    } else if (supported === false) {
      setStoreData('event', 'routeChangeError', RouterChangeReason.invalid + getRandomNumber());
    } else {
      next();
    }
  };
}

// 导出各功能的路由守卫
export const memoryGuard = createSupportGuard('memorySupported');
export const networkAdapterGuard = createSupportGuard('networkAdapterSupported');
export const snmpTrapGuard = createSupportGuard('snmpTrapSupported');
export const storageSupportedGuard = createSupportGuard('storageSupported');
export const fruListGuard = createSupportGuard('fruListSupported');

// processorSupported 是对象结构 { CPU: boolean | null, NPU: boolean | null }，需要特殊处理
export function processorGuard(
  to: RouteLocationNormalized,
  from: RouteLocationNormalized,
  next: NavigationGuardNext,
): void {
  const supported = getStoreData('loct', 'processorSupported') as { CPU: boolean | null; NPU: boolean | null };
  
  // 数据未就绪（CPU 和 NPU 都是 null），调用接口兜底
  if (supported?.CPU === null && supported?.NPU === null) {
    getGenericInfo().then(res => {
      if (!res.processorSupported?.CPU && !res.processorSupported?.NPU) {
        setStoreData('event', 'routeChangeError', RouterChangeReason.invalid + getRandomNumber());
      } else {
        next();
      }
    });
    return;
  }
  
  // 当 CPU 和 NPU 都不支持时，阻止导航
  if (!supported?.CPU && !supported?.NPU) {
    setStoreData('event', 'routeChangeError', RouterChangeReason.invalid + getRandomNumber());
  } else {
    next();
  }
}

export function monitorGuard(
  to: RouteLocationNormalized,
  from: RouteLocationNormalized,
  next: NavigationGuardNext,
): void {
  const processorSupported = getStoreData('loct', 'processorSupported');
  const memorySupported = getStoreData('loct', 'memorySupported');
  const storageSupported = getStoreData('loct', 'storageSupported');
  const networkAdapterSupported = getStoreData('loct', 'networkAdapterSupported');
  const ibmaspt = getStoreData('loct', 'ibmaspt');

  // 数据未就绪时（核心字段为 null），调用接口兜底
  if (processorSupported?.CPU === null || memorySupported === null) {
    getGenericInfo().then(res => {
      const cpuOk = res.processorSupported?.CPU;
      const otherOk = (res.memorySupported || res.storageSupported || res.networkAdapterSupported) && res.ibmaSupport;
      if (!cpuOk && !otherOk) {
        setStoreData('event', 'routeChangeError', RouterChangeReason.invalid + getRandomNumber());
      } else {
        next();
      }
    });
    return;
  }

  // CPU 不支持
  const cpuNotSupported = !processorSupported?.CPU;
  // 内存/磁盘/网卡至少有一个支持
  const hasOtherHardwareSupport = memorySupported || storageSupported || networkAdapterSupported;
  // 阻止导航：CPU 不支持 且 （内存/磁盘/网卡都不支持 或 ibmaspt 不支持）
  if (cpuNotSupported && (!hasOtherHardwareSupport || !ibmaspt)) {
    setStoreData('event', 'routeChangeError', RouterChangeReason.invalid + getRandomNumber());
  } else {
    next();
  }
}

export function powerCapGuard(
  to: RouteLocationNormalized,
  from: RouteLocationNormalized,
  next: NavigationGuardNext,
): void {
  const powerWaveRecordSupported = getStoreData('loct', 'powerWaveRecordSupported');
  
  // 数据未就绪时（全是 null），调用接口兜底
  const allNull = Object.values(powerWaveRecordSupported ?? {}).every(v => v === null);
  if (allNull) {
    getGenericInfo().then(res => {
      const hasSupport = Object.values(res.powerWaveRecordSupported ?? {}).some(Boolean);
      if (!hasSupport) {
        setStoreData('event', 'routeChangeError', RouterChangeReason.invalid + getRandomNumber());
      } else {
        next();
      }
    });
    return;
  }
  
  // 阻止导航：当各种功率信息都不支持时
  const powerSupported = Object.values(powerWaveRecordSupported ?? {}).some(Boolean);
  if (!powerSupported) {
    setStoreData('event', 'routeChangeError', RouterChangeReason.invalid + getRandomNumber());
  } else {
    next();
  }
}
