// cell update [<locator>] - Update packages from remote sources
//
// Usage:
//   cell update              Update all packages
//   cell update .            Update current directory package
//   cell update <locator>    Update a specific package
//
// Options:
//   --target <triple>    Target platform for build
//   --follow-links       Update link targets instead of origins
//   --git                Run git pull on local packages before updating

var shop = use('internal/shop')
var fd = use('fd')
var os = use('internal/os')
var link = use('link')

var target_pkg = null
var target_triple = null
var follow_links = false
var git_pull = false
var i = 0
var updated = 0
var packages = null

var run = function() {
  for (i = 0; i < length(args); i++) {
    if (args[i] == '--help' || args[i] == '-h') {
      log.console("Usage: cell update [<locator>] [options]")
      log.console("")
      log.console("Update packages from remote sources.")
      log.console("")
      log.console("Options:")
      log.console("  --target <triple>    Target platform for build")
      log.console("  --follow-links       Update link targets instead of origins")
      log.console("  --git                Run git pull on local packages")
      return
    } else if (args[i] == '--target' || args[i] == '-t') {
      if (i + 1 < length(args)) {
        target_triple = args[++i]
      } else {
        log.error('--target requires a triple')
        return
      }
    } else if (args[i] == '--follow-links') {
    follow_links = true
  } else if (args[i] == '--git') {
    git_pull = true
  } else if (!starts_with(args[i], '-')) {
    target_pkg = args[i]
  }
}

if (target_pkg)
  target_pkg = shop.resolve_locator(target_pkg)

function update_one(pkg) {
  var effective_pkg = pkg
  var link_target = null
  var lock = shop.load_lock()
  var old_entry = lock[pkg]
  var old_commit = old_entry ? old_entry.commit : null
  var info = shop.resolve_package_info(pkg)
  var new_entry = null
  var old_str = null

  if (follow_links) {
    link_target = link.get_target(pkg)
    if (link_target) {
      effective_pkg = link_target
      log.console("  Following link: " + pkg + " -> " + effective_pkg)
    }
  }

  // For local packages with --git, pull first
  if (git_pull && info == 'local' && fd.is_dir(effective_pkg + '/.git')) {
    log.console("  " + effective_pkg + " (git pull)")
    os.system('git -C "' + effective_pkg + '" pull')
  }

  // Check for update (sets lock entry if changed)
  new_entry = shop.update(effective_pkg)

  if (new_entry && new_entry.commit) {
    old_str = old_commit ? text(old_commit, 0, 8) : "(new)"
    log.console("  " + effective_pkg + " " + old_str + " -> " + text(new_entry.commit, 0, 8))
  }

  // Sync: fetch, extract, build
  shop.sync(effective_pkg, {target: target_triple})

  return new_entry
}

if (target_pkg) {
  if (update_one(target_pkg)) {
    log.console("Updated " + target_pkg + ".")
  } else {
    log.console(target_pkg + " is up to date.")
  }
} else {
  packages = shop.list_packages()
  log.console("Checking for updates (" + text(length(packages)) + " packages)...")

  arrfor(packages, function(pkg) {
    if (pkg == 'core') return
    if (update_one(pkg))
      updated = updated + 1
  })

  if (updated > 0) {
    log.console("Updated " + text(updated) + " package(s).")
  } else {
    log.console("All packages are up to date.")
  }
}
}
run()

$stop()
