// cell config - Manage system and actor configurations

var io = use('io')
var toml = use('toml')
var shop = use('shop')
var text = use('text')

function print_help() {
  log.console("Usage: cell config <command> [options]")
  log.console("")
  log.console("Commands:")
  log.console("  get <key>                    Get a configuration value")
  log.console("  set <key> <value>            Set a configuration value")
  log.console("  list                         List all configurations")
  log.console("  actor <name> get <key>       Get actor-specific config")
  log.console("  actor <name> set <key> <val> Set actor-specific config")
  log.console("  actor <name> list            List actor configurations")
  log.console("")
  log.console("Examples:")
  log.console("  cell config get system.ar_timer")
  log.console("  cell config set system.net_service 0.2")
  log.console("  cell config actor prosperon/_sdl_video set resolution 1920x1080")
  log.console("  cell config actor extramath/spline set precision high")
  log.console("")
  log.console("System keys:")
  log.console("  system.ar_timer         - Seconds before idle actor reclamation")
  log.console("  system.actor_memory     - MB of memory an actor can use (0=unbounded)")
  log.console("  system.net_service      - Seconds per network service pull")
  log.console("  system.reply_timeout    - Seconds to hold callback for replies (0=unbounded)")
  log.console("  system.actor_max        - Max number of simultaneous actors")
  log.console("  system.stack_max        - MB of memory each actor's stack can grow to")
}

// Parse a dot-notation key into path segments
function parse_key(key) {
  return key.split('.')
}

// Get a value from nested object using path
function get_nested(obj, path) {
  var current = obj
  for (var segment of path) {
    if (!current || typeof current != 'object') return null
    current = current[segment]
  }
  return current
}

// Set a value in nested object using path
function set_nested(obj, path, value) {
  var current = obj
  for (var i = 0; i < path.length - 1; i++) {
    var segment = path[i]
    if (!current[segment] || typeof current[segment] != 'object') {
      current[segment] = {}
    }
    current = current[segment]
  }
  current[path[path.length - 1]] = value
}

// Parse value string into appropriate type
function parse_value(str) {
  // Boolean
  if (str == 'true') return true
  if (str == 'false') return false
  
  // Number (including underscores)
  var num_str = str.replace(/_/g, '')
  if (/^-?\d+$/.test(num_str)) return parseInt(num_str)
  if (/^-?\d*\.\d+$/.test(num_str)) return parseFloat(num_str)
  
  // String
  return str
}

// Format value for display
function format_value(val) {
  if (typeof val == 'string') return '"' + val + '"'
  if (typeof val == 'number' && val >= 1000) {
    // Add underscores to large numbers
    return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '_')
  }
  return String(val)
}

// Print configuration tree recursively
function print_config(obj, prefix = '') {
  for (var key in obj) {
    var val = obj[key]
    var full_key = prefix ? prefix + '.' + key : key
    
    if (val && typeof val == 'object' && !Array.isArray(val)) {
      print_config(val, full_key)
    } else {
      log.console(full_key + ' = ' + format_value(val))
    }
  }
}

// Main command handling
if (args.length == 0) {
  print_help()
  $_.stop()
  return
}

var config = shop.load_config()
if (!config) {
  log.error("Failed to load .cell/cell.toml")
  $_.stop()
  return
}

var command = args[0]

switch (command) {
  case 'help':
  case '-h':
  case '--help':
    print_help()
    break
    
  case 'list':
    log.console("# Cell Configuration")
    log.console("")
    print_config(config)
    break
    
  case 'get':
    if (args.length < 2) {
      log.error("Usage: cell config get <key>")
      $_.stop()
      return
    }
    var key = args[1]
    var path = parse_key(key)
    var value = get_nested(config, path)
    
    if (value == null) {
      log.error("Key not found: " + key)
    } else if (value && typeof value == 'object' && !Array.isArray(value)) {
      // Print all nested values
      print_config(value, key)
    } else {
      log.console(key + ' = ' + format_value(value))
    }
    break
    
  case 'set':
    if (args.length < 3) {
      log.error("Usage: cell config set <key> <value>")
      $_.stop()
      return
    }
    var key = args[1]
    var value_str = args[2]
    var path = parse_key(key)
    var value = parse_value(value_str)
    
    // Validate system keys
    if (path[0] == 'system') {
      var valid_system_keys = [
        'ar_timer', 'actor_memory', 'net_service', 
        'reply_timeout', 'actor_max', 'stack_max'
      ]
      if (!valid_system_keys.includes(path[1])) {
        log.error("Invalid system key. Valid keys: " + valid_system_keys.join(', '))
        $_.stop()
        return
      }
    }
    
    set_nested(config, path, value)
    shop.save_config(config)
    log.console("Set " + key + " = " + format_value(value))
    break
    
  case 'actor':
    // Handle actor-specific configuration
    if (args.length < 3) {
      log.error("Usage: cell config actor <name> <command> [options]")
      $_.stop()
      return
    }
    
    var actor_name = args[1]
    var actor_cmd = args[2]
    
    // Initialize actors section if needed
    config.actors = config.actors || {}
    config.actors[actor_name] = config.actors[actor_name] || {}
    
    switch (actor_cmd) {
      case 'list':
        if (Object.keys(config.actors[actor_name]).length == 0) {
          log.console("No configuration for actor: " + actor_name)
        } else {
          log.console("# Configuration for actor: " + actor_name)
          log.console("")
          print_config(config.actors[actor_name], 'actors.' + actor_name)
        }
        break
        
      case 'get':
        if (args.length < 4) {
          log.error("Usage: cell config actor <name> get <key>")
          $_.stop()
          return
        }
        var key = args[3]
        var path = parse_key(key)
        var value = get_nested(config.actors[actor_name], path)
        
        if (value == null) {
          log.error("Key not found for actor " + actor_name + ": " + key)
        } else {
          log.console('actors.' + actor_name + '.' + key + ' = ' + format_value(value))
        }
        break
        
      case 'set':
        if (args.length < 5) {
          log.error("Usage: cell config actor <name> set <key> <value>")
          $_.stop()
          return
        }
        var key = args[3]
        var value_str = args[4]
        var path = parse_key(key)
        var value = parse_value(value_str)
        
        set_nested(config.actors[actor_name], path, value)
        shop.save_config(config)
        log.console("Set actors." + actor_name + "." + key + " = " + format_value(value))
        break
        
      default:
        log.error("Unknown actor command: " + actor_cmd)
        log.console("Valid commands: list, get, set")
    }
    break
    
  default:
    log.error("Unknown command: " + command)
    print_help()
}

$_.stop()