# Example, just for fun

# Just tell anybody or the "world" hello
def "nur hello" [
    name: string = "world"  # The name to say hello to
] {
    print $"hello ($name)"
}

# Actual useful tasks

# Setup local environment and install deps
def "nur install" [] {
    cargo fetch

    init-pre-commit
}

# Update local dev environment
def "nur update" [] {
    cargo fetch
}

# Run cargo
def --wrapped "nur cargo" [...args: string] {
    cargo ...$args
}

# Run cargo build
def --wrapped "nur build" [...args: string] {
    cargo "build" ...$args
}

# Run cargo run
def --wrapped "nur run" [...args: string] {
    cargo "run" ...$args
}

# Run tests
def "nur test" [
    --coverage
] {
    if $coverage {
        cargo tarpaulin --exclude-files _*
    } else {
        cargo test
    }
}

# Run nur nuscript tests
def "nur test-nur" [] {
    cd nur-tests

    cargo run -- --quiet prepare
    cargo run -- --quiet run-all
}

# Run one task for all enabled features to see those compile
def "nur test-features" [] {
    open Cargo.toml | get features | transpose key value | get key | each {
        |it|
        print $"Running 'nur hello ($it)' to check feature ($it)"
        cargo run -F $it -- --quiet hello $it
    }
}

# Run linter (clippy)
def --wrapped "nur lint" [
    ...args
] {
    cargo clippy ...$args
}

# Run all QA tasks
def "nur qa" [] {
    print "Running rust tests"
    nur test
    print "Running nur tests"
    nur test-nur
    print "Running feature tests"
    nur test-features
    print "Running clippy linter"
    nur lint
    print "Running cargo check"
    nur cargo check
    print "Running cargo fmt"
    nur cargo fmt
}

# Update version in Cargo.toml
def "nur version" [
    version: string
] {
    let parsed_version = $version | parse --regex '^(?P<major>[0-9]+)\.(?P<minor>[0-9]+)\.(?P<patch>[0-9]+)(-rc(?P<rc>[0-9]+))?$'
    if ($parsed_version | is-empty) {
        error make { msg: "No valid version string provided" }
    }
    cargo set-version $version
}

# Publish to crates.io
def "nur publish" [] {
    cargo publish
}

# Update version and release to crates.io
def "nur release" [
    version: string
] {
    print $"Updating to version (ansi purple)($version)(ansi reset)"
    nur version $version

    print ""
    print $"Creating release commit and tag '(ansi purple)v($version)(ansi reset)'"
    git add Cargo.toml Cargo.lock
    git commit -m $"release: 🔖 v($version)"
    git tag $"v($version)"

    print ""
    print "Publishing to crates.io"
    nur publish

    print ""
    print $"(ansi yellow)Don't forget to push last commit + tags to github!(ansi reset)"
}

# Update nu dependencies to version
def "nur upgrade-nu" [
    version: string
] {
    print $"Updating all required nu packages to (ansi purple)($version)(ansi reset)"
    open Cargo.toml | get dependencies | transpose key value | each {
        |it| if ($it.key starts-with "nu-") and not ($it.key == "nu-ansi-term") {
            try {
                cargo add $"($it.key)@($version)" (if $it.value.optional {"--optional"})
            } catch {
                cargo add $"($it.key)@($version)"
            }
        }
    }

    print ""
    print $"Storing version (ansi purple)($version)(ansi reset) in src/nu_version.rs as NU_VERSION constant"
    $"pub\(crate) const NU_VERSION: &str = \"($version)\";\n" | save -f src/nu_version.rs

    print ""
    print $"(ansi yellow)IMPORTANT: Please ensure all other packages are also upgraded accordingly:(ansi reset)"
    print $" -> (ansi cyan)nu-ansi-term(ansi reset): needs to be the same version as used in (ansi cyan)nu(ansi reset)"
    print $" -> (ansi cyan)miette(ansi reset): needs to be the same version as used in (ansi cyan)nu(ansi reset)"
    print $" -> (ansi cyan)openssl(ansi reset): needs to be the same version as used in (ansi cyan)nu(ansi reset)"
    print $" -> See nushell/Cargo.toml in section (ansi cyan)[workspace.dependencies](ansi reset) for details on used versions"
}

# Utility commands

def init-pre-commit [] {
    if (which pre-commit | is-empty) {
        print -e $"(ansi red)You don't have pre-commit installed locally, pre-commit hooks cannot be initialized(ansi reset)"
        return null
    }

    pre-commit install --install-hooks
}
