export type AuthSource = 'global' | 'object' | 'both';

export interface AuthDirectiveBindingValue {
  code: string | string[];
  source?: AuthSource;
}

export interface AuthDirectiveCodeSource {
  globalButtonCodes: string[];
  objectButtonCodes: string[];
}

function normalizeCodes(codes: string | string[]) {
  return Array.isArray(codes) ? codes : [codes];
}

function includesAny(sourceCodes: string[], targetCodes: string[]) {
  return targetCodes.some(code => sourceCodes.includes(code));
}

export function resolveAuthVisible(
  bindingValue: string | AuthDirectiveBindingValue,
  codeSource: AuthDirectiveCodeSource
) {
  const resolvedBinding =
    typeof bindingValue === 'string'
      ? {
          code: bindingValue,
          source: 'global' as const
        }
      : bindingValue;

  const targetCodes = normalizeCodes(resolvedBinding.code);
  const hasGlobal = includesAny(codeSource.globalButtonCodes, targetCodes);
  const hasObject = includesAny(codeSource.objectButtonCodes, targetCodes);

  if (resolvedBinding.source === 'object') {
    return hasObject;
  }

  if (resolvedBinding.source === 'both') {
    return hasGlobal || hasObject;
  }

  return hasGlobal;
}
