import type { AttributeType, EntryType } from './types';

export interface ConditionOption {
  label: string;
  tooltip?: string;
  value: string;
}

// Condition (operator) option lists per attribute type.
export const NUMERIC_CONDITION: ConditionOption[] = [
  { value: '=', label: '=' },
  { value: '!=', label: '!=' },
  { value: '>', label: '>' },
  { value: '<', label: '<' },
  { value: 'is_reported', label: 'is reported' },
  { value: 'is_not_reported', label: 'is not reported' }
];

export const STRING_CONDITION: ConditionOption[] = [
  { value: 'matches', label: 'matches', tooltip: 'Variable is reported and matches string (% for wildcard)' },
  { value: 'not_match', label: 'doesn\'t match', tooltip: 'Variable is reported and doesn\'t match string (% for wildcard)' },
  { value: '=', label: 'is', tooltip: 'Variable is reported and is the given string' },
  { value: '!=', label: 'is not', tooltip: 'Variable is reported and is not the given string' },
  { value: 'regex_matches', label: 'regex matches', tooltip: 'Variable is reported and matches the regular expression (POSIX regex)' },
  { value: 'regex_not_match', label: 'regex doesn\'t match', tooltip: 'Variable is reported and doesn\'t match the regular expression (POSIX regex)' },
  { value: 'is_reported', label: 'is reported', tooltip: 'Variable is reported' },
  { value: 'is_not_reported', label: 'is not reported', tooltip: 'Variable is not reported' }
];

export const LIST_CONDITION: ConditionOption[] = [
  { value: 'contains', label: 'contains', tooltip: 'List variable is reported and at least one item of the list contains the given string (% for wildcard)' },
  { value: 'not_contain', label: 'doesn\'t contain', tooltip: 'List variable is reported and no items of the list contains the given string (% for wildcard)' },
  { value: 'matches', label: 'matches', tooltip: 'List variable is reported and at least one item of the list match the given string' },
  { value: 'not_match', label: 'doesn\'t match', tooltip: 'List variable is reported and no items of the list match the given string' },
  { value: 'is_reported', label: 'is reported', tooltip: 'Variable is reported' },
  { value: 'is_not_reported', label: 'is not reported', tooltip: 'Variable is not reported' }
];

export const CONTEXT_CONDITION: ConditionOption[] = [
  { value: 'matches', label: 'matches' },
  { value: 'not_match', label: 'doesn\'t match' },
  { value: '=', label: 'is' },
  { value: '!=', label: 'is not' },
  { value: 'is_reported', label: 'is reported' },
  { value: 'is_not_reported', label: 'is not reported' }
];

export const DATE_CONDITION: ConditionOption[] = [
  { value: '<', label: 'before' },
  { value: '>', label: 'after' },
  { value: 'is_reported', label: 'is reported' },
  { value: 'is_not_reported', label: 'is not reported' }
];

// The set of types a user can switch a rule to via the "change type" select.
export const FIELD_TYPES: { label: string; value: AttributeType }[] = [
  { value: 'string', label: 'string' },
  { value: 'int', label: 'integer' },
  { value: 'real', label: 'real' },
  { value: 'slist', label: 'list' },
  { value: 'context', label: 'context' }
];

// Conditions where the value input is irrelevant (variable presence checks).
export const VALUELESS_CONDITIONS = ['is_reported', 'is_not_reported'];

// Map an attribute type to its condition option list.
export const conditionsForType = (type?: AttributeType): ConditionOption[] => {
  switch (type) {
    case 'slist':
      return LIST_CONDITION;
    case 'int':
    case 'real':
      return NUMERIC_CONDITION;
    case 'date':
      return DATE_CONDITION;
    case 'context':
      return CONTEXT_CONDITION;
    case 'string':
    default:
      return STRING_CONDITION;
  }
};

// UI condition -> backend operator. Mostly identity; kept explicit so a UI
// label change can't silently alter the payload.
export const INVENTORY_FILTER_OPERATORS: Record<string, string> = {
  '<': '<',
  '>': '>',
  '=': '=',
  '!=': '!=',
  '<=': '<=',
  '>=': '>=',
  matches: 'matches',
  not_match: 'not_match',
  contains: 'contains',
  not_contain: 'not_contain',
  regex_matches: 'regex_matches',
  regex_not_match: 'regex_not_match',
  is_reported: 'is_reported',
  is_not_reported: 'is_not_reported'
};

// Classes offered by default in the attribute picker's "Classes" section.
export const DEFAULT_INVENTORY_FILTER_CLASSES = [
  'centos',
  'coreos',
  'redhat_pure',
  'debian_pure',
  'suse',
  'ubuntu',
  'solaris',
  'hpux',
  'aix',
  'windows'
];

// Virtual attribute label used to carry a free-text host search query.
export const HOST_SEARCH_ATTRIBUTE = 'cfHostSearchQuery';

// Entry type -> the inventory attribute + operator used to resolve entries to
// real hosts.
export const ENTRY_TYPE_RESOLUTION: Record<EntryType, { attribute: string; operator: string }> = {
  ip: { attribute: 'IPv4 addresses', operator: 'or|contains' },
  hostkey: { attribute: 'hostkey', operator: 'or|matches' },
  hostname: { attribute: 'Host name', operator: 'or|matches' },
  mac: { attribute: 'MAC addresses', operator: 'or|contains' },
  ip_mask: { attribute: 'IPv4 addresses', operator: 'or|ip_mask' }
};

export const ENTRY_TYPES: EntryType[] = ['hostkey', 'ip', 'hostname', 'mac'];

// Search-query classification patterns.
export const VALIDATION_PATTERNS = {
  IP: /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/,
  IP_MASK: /(\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}\/([1-9]$|[1-2][0-9]$|3[0-2]$)/,
  HOSTNAME: /^(([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])\.)*([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])$/
};

export const SEARCH_DEBOUNCE_DELAY = 400;
export const DEFAULT_SEARCH_RESULT_COUNT = 8;
