#!/usr/bin/env bash
set -euo pipefail
source "$SHELLOPS_DIR/.envrc"
import "$SHELLOPS_DIR/lib/cargo/api.sh"
import "$SHELLOPS_DIR/lib/manifest.api.sh"

USAGE="$(cat <<EOF
Updates Cargo.toml and Cargo.lock to match a given version.

Usage: action rust sync-cargo-version [options] <version>

Arguments:
  version          Semver version (e.g., 1.2.3 or 1.0.0-rc.1)

Options:
  --crate <name>        Target a specific crate by package name.
                        Defaults to manifest command-name.

  --workspace           Update the workspace-level version directly
                        ([workspace.package] in root Cargo.toml).

  --cargo-path <path>   Path to a Cargo.toml to start from.
                        Defaults to project root.
                        Use for polyglot repos where Rust isn't at the project root.

  -h, --help            Show this help text.
EOF
)"

REGEX_SEMVER='^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z]+(\.[0-9]+)?)?$'
ARG_VERSION=""
ARG_CRATE=""
ARG_WORKSPACE=false
ARG_CARGO_PATH=""

function main() {
  parse_args "$@"

  if [[ "$ARG_WORKSPACE" == true ]]; then
    cargo_set_workspace_version "$ARG_VERSION" "$ARG_CARGO_PATH"
    return
  fi

  local package_name="${ARG_CRATE}"
  if [[ -z "$package_name" ]]; then
    package_name="$(manifest_get command_name)"
  fi

  cargo_set_crate_version "$package_name" "$ARG_VERSION" "$ARG_CARGO_PATH"
}

function parse_args() {
  while [[ $# -gt 0 ]]; do
    case "$1" in
      -h|--help) log "$USAGE" && exit 0 ;;
      --crate) ARG_CRATE="$2"; shift ;;
      --workspace) ARG_WORKSPACE=true ;;
      --cargo-path) ARG_CARGO_PATH="$2"; shift ;;
      -*)
        error "Unknown option: $1"
        log "$USAGE"
        exit 1
        ;;
      *)
        if [[ ! "$1" =~ $REGEX_SEMVER ]]; then
          error "Invalid semver: $1"
          log "$USAGE"
          exit 1
        fi
        ARG_VERSION="$1"
        ;;
    esac
    shift
  done

  if [[ -z "$ARG_VERSION" ]]; then
    error "version not supplied"
    log "$USAGE"
    exit 1
  fi
}

main "$@"
