//  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 { updateUser } from '@/services/security-enhance.service';
import { traduction } from '@/utils/language';
import {
  IAccount,
  IAuthorityData,
  IAuthorityEnum,
  IFormOption,
  ILoginFailOption,
  SSHAuthenticationMode,
} from '../models/security.datatype';

export const inactivityValid = (param: number[]) => {
  return {
    type: 'number',
    message: traduction('SECURITY_PERIOD_NOLIMITED'),
    trigger: 'change',
    transform: (value: string) => {
      return Number(value);
    },
    validator: (rule: any, value: any, callback: (error?: Error) => void) => {
      if (value === 0 || (value >= param[0] && value <= param[1])) {
        callback();
      } else {
        callback(new Error());
      }
    },
  };
};

export const periodValid = (leastPeriod: number) => {
  return {
    type: 'number',
    message: traduction('VALIDATOR_PASSWORD_USAGE_PERIOD'),
    trigger: 'change',
    transform: (value: string) => {
      return Number(value);
    },
    validator: (rule: any, value: any, callback: (error?: Error) => void) => {
      if (value !== 0 && leastPeriod >= 355) {
        rule.message = traduction('VALIDATOR_PASSWORD_USAGE_PERIOD');
        callback(new Error());
      } else if (value !== 0 && leastPeriod !== 0 && value - 10 <= leastPeriod) {
        rule.message = traduction('VALIDATOR_PASSWORD_PERIOD_BIG');
        callback(new Error());
      } else {
        callback();
      }
    },
  };
};

export const leastPeriodValid = (period: number) => {
  return {
    type: 'number',
    message: traduction('VALIDATOR_PASSWORD_USAGE_PERIOD'),
    trigger: 'change',
    transform: (value: string) => {
      return Number(value);
    },
    validator: (rule: any, value: any, callback: (error?: Error) => void) => {
      if (value !== 0 && period > 0 && period < 10) {
        rule.message = traduction('VALIDATOR_VALIDATOR_PASSWORD_ONLY');
        callback(new Error());
      } else if (value !== 0 && period !== 0 && value + 10 >= period) {
        rule.message = traduction('VALIDATOR_PASSWORD_PERIOD_BIG');
        callback(new Error());
      } else {
        callback();
      }
    },
  };
};

function getUserArr(availableUsers: any) {
  const userArr: IAccount[] = [
    {
      value: '',
      label: '[NULL]',
    },
  ];

  if (availableUsers?.length) {
    availableUsers.forEach((userItem: any) => {
      userArr.push({
        value: userItem,
        label: userItem,
      });
    });
  }
  return userArr;
}

export function factoryEnhanceData(securityInfo: any): IAuthorityData {
  const {
    SystemLockDownEnabled: systemLockDownEnabled,
    OSAdministratorPrivilegeEnabled,
    PasswordComplexityCheckEnabled: passwordComplexityCheckEnabled,
    SSHAuthenticationMode: sshPasswordAuthenticationEnabled,
    PasswordValidityDays: passwordValidityDays,
    EmergencyLoginUser: emergencyLoginUser,
    PreviousPasswordsDisallowedCount: previousPasswordsDisallowedCount,
    MaxPreviousPasswordsDisallowedCount: MaxPreviousPasswordsDisallowedCount,
    MinimumPasswordAgeDays: minimumPasswordAgeDays,
    MinimumPasswordLength: minimumPasswordLength,
    AccountInactiveTimelimitDays: accountInactiveTimelimit,
    CertificateOverdueWarningTime: certificateOverdueWarningTime,
    TLSVersion: tlsVersion,
    'TLS1.2Configurable': tls12Configurable,
    AccountLockoutThreshold: accountLockoutThreshold,
    MaxAccountLockoutThreshold: MaxAccountLockoutThreshold,
    AccountLockoutDuration: accountLockoutDuration,
    MaxAccountLockoutDuration: MaxAccountLockoutDuration,
    AvailableUsers: availableUsers,
    AntiDNSRebindEnabled: antiDNSRebindEnabled,
    TLSSupported: tlsSupported,
    CRLOverdueWarningMode: crlOverdueWarningMode,
    CRLOverdueWarningTime: crlOverdueWarningTime,
    LocalAccountPasswordRulePolicy: localAccountPasswordRulePolicy,
    LocalAccountPasswordPattern: localAccountPasswordPattern,
    SnmpCommunityPasswordRulePolicy: snmpCommunityPasswordRulePolicy,
    SnmpCommunityPasswordPattern: snmpCommunityPasswordPattern,
    VNCPasswordRulePolicy: vncPasswordRulePolicy,
    VNCPasswordPattern: vncPasswordPattern,
  } = securityInfo;

  const result: IAuthorityData = {
    user: getUserArr(availableUsers),
    systemLockDownEnabled,
    OSAdministratorPrivilegeEnabled,
    passwordComplexityCheckEnabled,
    tls12Configurable,
    sshPasswordAuthenticationEnabled:
      sshPasswordAuthenticationEnabled === SSHAuthenticationMode.password,
    passwordValidityDays: passwordValidityDays || 0,
    emergencyLoginUser,
    previousPasswordsDisallowedCount: previousPasswordsDisallowedCount || 0,
    MaxPreviousPasswordsDisallowedCount: MaxPreviousPasswordsDisallowedCount || 0,
    minimumPasswordAgeDays: minimumPasswordAgeDays || 0,
    minimumPasswordLength,
    accountInactiveTimelimit,
    certificateOverdueWarningTime,
    tlsVersion,
    accountLockoutThreshold,
    MaxAccountLockoutThreshold,
    accountLockoutDuration,
    MaxAccountLockoutDuration,
    antiDNSRebindEnabled,
    tlsSupported,
    crlOverdueWarningMode,
    crlOverdueWarningTime,
    localAccountPasswordRulePolicy,
    localAccountPasswordPattern,
    snmpCommunityPasswordRulePolicy,
    snmpCommunityPasswordPattern,
    vncPasswordRulePolicy,
    vncPasswordPattern,
  };
  if (securityInfo.error) {
    result.error = securityInfo.error;
  }
  return result;
}

export function formatSecInfo(securityInfo: any) {
  if (securityInfo.error) {
    const tempSecInfo: any = Object.assign({}, securityInfo.data);
    tempSecInfo.error = securityInfo.error;
    return tempSecInfo;
  }
  return securityInfo;
}

export function inputBlurFn(input: any) {
  const targetArr = ['loginFailInput', 'localAccountPasswordPattern', 'snmpCommunityPasswordPattern', 'vncPasswordPattern'];
  // V2 loginFailInput输入为空，显示为空
  if (input.value === '' && !targetArr.includes(input.id)) {
    input.value = input.recommendValue || '0';
  }
}

export function initLoginFailOpt(): ILoginFailOption[] {
  const options = [];
  for (let j = 0; j < 7; j++) {
    let isIgnoreTime = false;
    let labelValue = String(j);
    if (j === 0) {
      labelValue = traduction('SECURITY_UNLIMITED');
      isIgnoreTime = true;
    }
    options.push({
      value: j,
      label: labelValue,
      isIgnoreTime,
    });
  }
  return options;
}

export function isEqual(a: any, b: any): boolean {
  if (a === undefined || a === null) {
    return false;
  }
  if (b === undefined || b === null) {
    return false;
  }
  if (typeof a !== typeof b) {
    return false;
  }
  if (typeof a === 'object') {
    const aKeys = Object.keys(a);
    const bKeys = Object.keys(b);
    if (aKeys.length !== bKeys.length) {
      return false;
    }

    for (const key of aKeys) {
      if (!isEqual(a[key], b[key])) {
        return false;
      }
    }

    return true;
  }

  return a === b;
}

export function getShowedComps(comps: IFormOption[]): IFormOption[] {
  return comps.filter(comp => comp.show !== false);
}

export function saveParams(forms: IFormOption[], type: boolean): any {
  const params: any = {};
  let tlsArr = [];
  for (const form of forms) {
    if (form.associated === IAuthorityEnum.accountLockoutThreshold) {
      if (form.locked) {
        params[form.associated] = 0; // 永不锁定传0
      } else {
        params[form.associated] = transformToNumber(form.value);
      }
      continue;
    }
    if (form.associated === IAuthorityEnum.accountLockoutDuration) {
      params[form.associated] = transformToNumber(form.value);
      continue;
    }
    if (!type) {
      if (form.associated === IAuthorityEnum.tlsVersion && form.value) {
        if (form.value === 'TLS1.2') {
          tlsArr.push('TLS1.2', 'TLS1.3');
        } else {
          tlsArr.push(form.value);
        }
        continue;
      }
    } else {
      if (form.associated === IAuthorityEnum.tlsVersion && form.value) {
        tlsArr = form.value;
        continue;
      }
    }
    if (form.associated === IAuthorityEnum.SSHPasswordAuthenticationEnabled) {
      params[form.associated] = form.value
        ? SSHAuthenticationMode.password
        : SSHAuthenticationMode.publicKey;
      continue;
    }

    // 不需要转number的字段
    if (form.associated === IAuthorityEnum.emergencyLoginUser) {
      params[form.associated] = form.value;
      continue;
    }

    if (typeof form.value === 'object') {
      params[form.associated] = form.value;
      continue;
    }
    params[form.associated] = transformToNumber(form.value);
  }

  if (tlsArr.length) {
    params.TLSVersion = tlsArr;
  }

  return updateUser(params);
}

function transformToNumber(str: string) {
  const transformed = parseInt(str, 10);
  if (isNaN(transformed)) {
    return str;
  }
  return transformed;
}
