# Copyright Sunhpc Project Developers. See COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

"""Defines paths that are part of Sunhpc's directory structure.

Do not import other ``sunhpc`` modules here. This module is used
throughout Sunhpc and should bring in a minimal number of external
dependencies.
"""

import os
from pathlib import PurePath, Path

#: This file lives in /opt/sunhpc/lib/sunhpc/sunhpc/paths.py
#: prefix: /opt/sunhpc
prefix = str(Path(__file__).parent.parent.parent.parent)

#: synonym for prefix
sunhpc_root = prefix

#: bin directory in the sunhpc prefix
bin_path = os.path.join(prefix, "bin")

#: var directory in the sunhpc
var_path = os.path.join(prefix, "var")

#: pkgs directory in the sunhpc
pkgs_path = os.path.join(var_path, "pkgs")

#: ipxe directory in the sunhpc
ipxe_path = os.path.join(pkgs_path, "ipxe")

#: scripts directory in the sunhpc
scripts_path = os.path.join(pkgs_path, "scripts")

#: The sunhpc script itself
sunhpc_command = os.path.join(bin_path, "sunhpc")

#: The sbang script in the sunhpc installation
sbang_script = os.path.join(bin_path, "sbang")

# sunhpc directory hierarchy
lib_path = os.path.join(prefix, "lib", "sunhpc")
module_path = os.path.join(lib_path, "sunhpc")
vendor_path = os.path.join(module_path, "vendor")
command_path = os.path.join(module_path, "cmd")
analyzers_path = os.path.join(module_path, "analyzers")
platform_path = os.path.join(module_path, "platforms")
compilers_path = os.path.join(module_path, "compilers")
operating_system_path = os.path.join(module_path, "operating_systems")
test_path = os.path.join(module_path, "test")
hooks_path = os.path.join(module_path, "hooks")
opt_path = os.path.join(prefix, "opt")
share_path = os.path.join(prefix, "share", "sunhpc")
etc_path = os.path.join(prefix, "etc", "sunhpc")

#
# Things in $sunhpc/etc/sunhpc
#
default_license_dir = os.path.join(etc_path, "licenses")

#
# Things in $sunhpc/var/sunhpc
#
var_path = os.path.join(prefix, "var", "sunhpc")

# read-only things in $sunhpc/var/sunhpc
repos_path = os.path.join(var_path, "repos")
test_repos_path = os.path.join(var_path, "test_repos")
mock_packages_path = os.path.join(test_repos_path, "sunhpc_repo", "builtin_mock")

#
# Writable things in $sunhpc/var/sunhpc
# TODO: Deprecate these, as we want a read-only sunhpc prefix by default.
# TODO: These should probably move to user cache, or some other location.
#
# fetch cache for downloaded files
default_fetch_cache_path = os.path.join(var_path, "cache")

# GPG paths.
gpg_keys_path = os.path.join(var_path, "gpg")
mock_gpg_data_path = os.path.join(var_path, "gpg.mock", "data")
mock_gpg_keys_path = os.path.join(var_path, "gpg.mock", "keys")
gpg_path = os.path.join(opt_path, "sunhpc", "gpg")


# Below paths are where Sunhpc can write information for the user.
# Some are caches, some are not exactly caches.
#
# The options that start with `default_` below are overridable in
# `config.yaml`, but they default to use `user_cache_path/<location>`.
#
# You can override the top-level directory (the user cache path) by
# setting `SUNHPC_USER_CACHE_PATH`. Otherwise it defaults to ~/.sunhpc.
#
def _get_user_cache_path():
    return os.path.expanduser(os.getenv("SUNHPC_USER_CACHE_PATH") or "~%s.sunhpc" % os.sep)


user_cache_path = str(PurePath(_get_user_cache_path()))

#: junit, cdash, etc. reports about builds
reports_path = os.path.join(user_cache_path, "reports")

#: installation test (sunhpc test) output
default_test_path = os.path.join(user_cache_path, "test")

#: sunhpc monitor analysis directories
default_monitor_path = os.path.join(reports_path, "monitor")

#: git repositories fetched to compare commits to versions
user_repos_cache_path = os.path.join(user_cache_path, "git_repos")

#: default location where remote package repositories are cloned
package_repos_path = os.path.join(user_cache_path, "package_repos")

#: bootstrap store for bootstrapping clingo and other tools
default_user_bootstrap_path = os.path.join(user_cache_path, "bootstrap")

# Below paths pull configuration from the host environment.
#
# There are three environment variables you can use to isolate sunhpc from
# the host environment:
# - `SUNHPC_USER_CONFIG_PATH`: override `~/.sunhpc` location (for config and caches)
# - `SUNHPC_SYSTEM_CONFIG_PATH`: override `/etc/sunhpc` configuration scope.
# - `SUNHPC_DISABLE_LOCAL_CONFIG`: disable both of these locations.


# User configuration and caches in $HOME/.sunhpc
def _get_user_config_path():
    return os.path.expanduser(os.getenv("SUNHPC_USER_CONFIG_PATH") or "~%s.sunhpc" % os.sep)


# Configuration in /etc/sunhpc on the system
def _get_system_config_path():
    return os.path.expanduser(
        os.getenv("SUNHPC_SYSTEM_CONFIG_PATH") or os.sep + os.path.join("etc", "sunhpc")
    )


#: User configuration location
user_config_path = _get_user_config_path()

#: System configuration location
system_config_path = _get_system_config_path()

#: Recorded directory where sunhpc command was originally invoked
sunhpc_working_dir = None


def set_working_dir():
    """Change the working directory to getcwd, or sunhpc prefix if no cwd."""
    global sunhpc_working_dir
    try:
        sunhpc_working_dir = os.getcwd()
    except OSError:
        os.chdir(prefix)
        sunhpc_working_dir = prefix
