###
# Define a set of utilities command to handle common tasks during Ra2m.
# These commands is targeted to be used by the user to ease his journey
# The CI and git-hook (if configured) also rely on them.
#
# NB: Init git-hook is simple as `just init-git-hook:
#  It will populate .git/hooks folder with script that run the associated
#  command in justfile (if exist)
#


# Common path variables
# Use to update path based on targeted crate
CRATE_LIST := "ra2m_sim ra2m_cpn ra2m_cpu ra2m"
WORKDIR := if env('TRGT_CRATE', '') =~ "^ra2m_(sim|cpn|cpu)$" { env_var('PWD') / env_var('TRGT_CRATE') } else { env_var('PWD') }

# Common color variables for beautifull prompt
# Default to Bold color
NC := '\033[0m'
RED := '\033[1;31m'
GREEN := '\033[1;32m'
ORANGE := '\033[1;33m'
BLUE := '\033[1;34m'

# Default command
default:
  just --list

# Display env for debug purpose
workdir:
  @echo {{WORKDIR}}

# Generic iteration over crates
run_trgt_over TRGT CRATE_L:
  #!/usr/bin/env bash
  for crate in {{CRATE_L}}; do
  export TRGT_CRATE=${crate};
    TRGT_CRATE=$crate;
    just "{{TRGT}}" || exit -1;
  done

# Formatter ###################################################################
fmt-check:
  @cd {{WORKDIR}} && cargo fmt --all -- --check
fmt-check-all:
  just run_trgt_over "fmt-check" "{{CRATE_LIST}}"
  @cd {{WORKDIR}} && cargo fmt --all

fmt:
  @cd {{WORKDIR}} && cargo fmt --all
fmt-all:
  just run_trgt_over "fmt" "{{CRATE_LIST}}"
  @cd {{WORKDIR}} && cargo fmt --all

# Linter ######################################################################
clippy:
  @cd {{WORKDIR}} && cargo clippy --all-targets -- --no-deps -D warnings
clippy-all:
  just run_trgt_over "clippy" "{{CRATE_LIST}}"

clippy-fix:
  @cd {{WORKDIR}} && cargo clippy --all-targets --fix -- --no-deps -D warnings

clippy-fix-all:
  just run_trgt_over "clippy-fix" "{{CRATE_LIST}}"
  @cd {{WORKDIR}} && cargo clippy --all-targets --fix -- --no-deps -D warnings

# Check #######################################################################
check:
  @cd {{WORKDIR}} && cargo check --all-targets
check-all:
  just run_trgt_over "check" "{{CRATE_LIST}}"

# test ########################################################################
test:
  @cd {{WORKDIR}} && cargo test --release --tests
test-all:
  just run_trgt_over "test" "{{CRATE_LIST}}"

# publish #####################################################################
publish-check:
  cargo publish --dry-run --workspace --allow-dirty
#NB: Real publish rely on github acion -> Cf. `.github/workflows/make_release.yml

# Git-hook related commands ###################################################
# NB: Not all git hook are defined
supported-git-hook:= "['commit-msg', 'pre-commit', 'pre-merge-commit', 'prepare-commit-msg', 'pre-push', 'pre-rebase']"

commit-msg:
  @echo -e "{{GREEN}} +commit-msg hook {{NC}}"
pre-commit:
  #!/usr/bin/env bash
  echo -e "{{GREEN}} +pre-commit hook {{NC}}"
  for crate in {{CRATE_LIST}}; do
    echo -e "{{GREEN}} +pre-commit hook:-> {{NC}} sub-crate folder {{ORANGE}} $crate {{NC}}"
    TRGT_CRATE=$crate;
    just fmt-check || exit $?;
  done

pre-merge-commit:
  @echo -e "{{GREEN}} +pre-merge-commit hook {{NC}}"
prepare-commit-msg:
  @echo -e "{{GREEN}} +prepare-commit-msg hook {{NC}}"
pre-push: && fmt-check clippy-all
  #!/usr/bin/env bash
  echo -e "{{GREEN}} +pre-push hook {{NC}}"
  for crate in {{CRATE_LIST}}; do
    echo -e "{{GREEN}} +pre-push hook:-> {{NC}} sub-crate folder {{ORANGE}} $crate {{NC}}"
    TRGT_CRATE=$crate;
    just fmt-check || exit $?;
    just clippy-all || exit $?;
  done

pre-rebase:
  @echo "+pre-rebase hook"

git-hook-init:
  #!/usr/bin/env python
  from pathlib import Path
  import os
  print("+Init git hook")
  git_hook_path=Path.cwd()/Path('.git/hooks')
  git_hook_path.mkdir(parents=True, exist_ok=True)
  for hook_name in {{supported-git-hook}}:
    print(f"Install {hook_name} git-hook")

    # Check if file already exists
    hook_file = git_hook_path / Path(hook_name)
    if hook_file.exists() and (hook_file).is_file():
      # File already exist: ask user it's intend
      print(f"Hook file {hook_file} already exist")
      user = None
      overwrite = False

      while not user in ['y', 'yes', 'n', 'no']:
        user = input("Would you want to overwrite it ? [y/n/d]")
        if user in ['d', 'display']:
          with open(hook_file.as_posix()) as file:
            print(file.read())
        elif user in ['y', 'yes']:
          overwrite = True
        elif user in ['n', 'no']:
          print(f"Skipped {hook_file.name}");
        else:
          print("Invalid option");

      if not(overwrite):
        continue

    # Get ride of previous content if any and generate simple hook script that redirect to just
    # command with same name as triggered hook
    with open(hook_file.as_posix(), 'w') as file:
      file.write("#!/usr/bin/env sh\n")
      file.write("# Simple script that execute associated just command. \n#\n\n")
      file.write("set -e\n")
      file.write(f"just {hook_name}\n")

    # Let generated file to be executable
    os.chmod(hook_file.as_posix(), 0o744)
