"""
Script to automate the build and release process for the dxlabs package.
Handles cleaning, building, validation, and uploading to PyPI/TestPyPI.
"""

import argparse
import os
import shutil
import subprocess
import sys


def clean():
    """
    Delete old build and dist directories.
    Ensures a fresh build by removing artifacts from previous runs.
    """
    print("--- Cleaning up old build/dist directories... ---")
    dirs_to_delete = ["dist", "build", "src/dxlabs.egg-info"]
    for directory in dirs_to_delete:
        if os.path.exists(directory):
            shutil.rmtree(directory)
            print(f"Deleted {directory}")


def build():
    """
    Build project into .tar.gz (sdist) and .whl (wheel).
    Uses the 'build' module to generate distribution files.
    """
    print("\n--- Building package... ---")
    try:
        subprocess.run([sys.executable, "-m", "build"], check=True)
    except subprocess.CalledProcessError:
        print(
            "Error: Build failed. Please ensure you have the 'build' library installed (pip install build)."
        )
        sys.exit(1)


def check():
    """
    Check package validity and metadata using twine.
    Ensures the generated files are compatible with PyPI requirements.
    """
    print("\n--- Checking package with twine... ---")
    try:
        subprocess.run([sys.executable, "-m", "twine", "check", "dist/*"], check=True)
    except subprocess.CalledProcessError:
        print("Error: Package check failed.")
        sys.exit(1)


def upload(test: bool = False):
    """
    Upload package to PyPI or TestPyPI using twine.

    Args:
        test (bool): If True, uploads to TestPyPI. Otherwise, uploads to official PyPI.
    """
    if test:
        print("\n--- Uploading to TestPyPI... ---")
        repo_args = ["--repository", "testpypi"]
    else:
        print("\n--- Uploading to official PyPI... ---")
        repo_args = []

    try:
        # Using --verbose to provide more feedback during the upload process
        cmd = (
            [sys.executable, "-m", "twine", "upload"]
            + repo_args
            + ["dist/*"]
            + ["--verbose"]
        )
        subprocess.run(cmd, check=True)
        print("\n--- Upload successful! ---")
    except subprocess.CalledProcessError:
        print("\nError: Upload failed. Please check your credentials and version number.")
        sys.exit(1)


def main():
    """
    Main entry point for the publish script.
    Parses arguments and coordinates the build/release workflow.
    """
    parser = argparse.ArgumentParser(
        description="Script to build and upload dxlabs package to PyPI."
    )
    parser.add_argument(
        "--test",
        action="store_true",
        help="Upload to TestPyPI instead of official PyPI.",
    )
    parser.add_argument(
        "--no-upload", action="store_true", help="Build and check only without uploading."
    )
    args = parser.parse_args()

    # Verify that the script is being run from the root directory
    if not os.path.exists("pyproject.toml"):
        print(
            "Error: Please run this script from the project root (where pyproject.toml is located)."
        )
        sys.exit(1)

    # Core workflow: Clean -> Build -> Check -> [Upload]
    clean()
    build()
    check()

    if not args.no_upload:
        upload(test=args.test)
    else:
        print("\n--- Build complete. Skipping upload step as requested. ---")


if __name__ == "__main__":
    main()
