/**
 * Built-in DSL Functions
 * 
 * Native functions for use in DSL expressions
 * Includes IP operations, time functions, string utilities
 */

// Use optimized fast versions for hot paths
import {
  isIpInCidrFast,
  isPrivateIpFast,
  ipToIntFast,
  isIPv4Fast
} from '../../utils/ip-utils-fast.js';
import {
  isIPv6,
  isLoopbackIp,
  ipEquals,
  getIpVersion
} from '../../utils/ip-utils.js';

/**
 * Registry of built-in functions
 */
export const BUILT_IN_FUNCTIONS = {
  // IP Address Functions - Using optimized fast versions
  ip_in_cidr: {
    params: ['ip', 'cidr'],
    evaluate: (ip, cidr) => {
      if (!ip || !cidr) return false;
      return isIpInCidrFast(String(ip), String(cidr));
    }
  },
  
  ip_equals: {
    params: ['ip1', 'ip2'],
    evaluate: (ip1, ip2) => {
      return ipEquals(String(ip1), String(ip2));
    }
  },
  
  ip_version: {
    params: ['ip'],
    evaluate: (ip) => {
      return getIpVersion(String(ip));
    }
  },
  
  ip_is_private: {
    params: ['ip'],
    evaluate: (ip) => {
      if (!ip) return false;
      return isPrivateIpFast(String(ip));
    }
  },
  
  ip_is_loopback: {
    params: ['ip'],
    evaluate: (ip) => {
      if (!ip) return false;
      // Fast check: 127.x.x.x
      return ipToIntFast(String(ip)) >>> 24 === 127;
    }
  },
  
  ip_is_v4: {
    params: ['ip'],
    evaluate: (ip) => {
      if (!ip) return false;
      return isIPv4Fast(String(ip));
    }
  },
  
  ip_is_v6: {
    params: ['ip'],
    evaluate: (ip) => {
      if (!ip) return false;
      return isIPv6(String(ip));
    }
  },
  
  // Time Functions
  hour_of_day: {
    params: ['timestamp'],
    evaluate: (timestamp) => {
      const ts = typeof timestamp === 'number' ? timestamp : Date.now();
      return new Date(ts).getHours();
    }
  },
  
  day_of_week: {
    params: ['timestamp'],
    evaluate: (timestamp) => {
      const ts = typeof timestamp === 'number' ? timestamp : Date.now();
      return new Date(ts).getDay(); // 0 = Sunday
    }
  },
  
  // String Functions
  contains: {
    params: ['string', 'substring'],
    evaluate: (str, substr) => {
      if (!str || !substr) return false;
      return String(str).includes(String(substr));
    }
  },
  
  starts_with: {
    params: ['string', 'prefix'],
    evaluate: (str, prefix) => {
      if (!str || !prefix) return false;
      return String(str).startsWith(String(prefix));
    }
  },
  
  ends_with: {
    params: ['string', 'suffix'],
    evaluate: (str, suffix) => {
      if (!str || !suffix) return false;
      return String(str).endsWith(String(suffix));
    }
  },
  
  // Comparison Functions
  equals: {
    params: ['a', 'b'],
    evaluate: (a, b) => a === b
  },
  
  greater_than: {
    params: ['a', 'b'],
    evaluate: (a, b) => a > b
  },
  
  less_than: {
    params: ['a', 'b'],
    evaluate: (a, b) => a < b
  },
  
  in_range: {
    params: ['value', 'min', 'max'],
    evaluate: (value, min, max) => value >= min && value <= max
  }
};

/**
 * Check if a function name is a built-in
 */
export function isBuiltInFunction(name) {
  return name in BUILT_IN_FUNCTIONS;
}

/**
 * Evaluate a built-in function
 */
export function evaluateBuiltIn(name, args) {
  const func = BUILT_IN_FUNCTIONS[name];
  if (!func) {
    throw new Error(`Unknown built-in function: ${name}`);
  }
  
  if (args.length !== func.params.length) {
    throw new Error(
      `Function ${name} expects ${func.params.length} arguments, got ${args.length}`
    );
  }
  
  return func.evaluate(...args);
}

/**
 * Get function signature
 */
export function getFunctionSignature(name) {
  const func = BUILT_IN_FUNCTIONS[name];
  if (!func) return null;
  
  return {
    name,
    params: func.params
  };
}
