"""
Tasks for maintaining the project.

Execute 'invoke --list' for guidance on using Invoke
"""
import shutil
import platform

from invoke import task
from pathlib import Path


ROOT_DIR = Path(__file__).parent
SETUP_FILE = ROOT_DIR.joinpath("setup.py")
TEST_DIR = ROOT_DIR.joinpath("tests")
SOURCE_DIR = ROOT_DIR.joinpath("spikex")
PYTHON_DIRS = [str(d) for d in (SOURCE_DIR, TEST_DIR)]


# def _delete_file(file):
#     try:
#         file.unlink(missing_ok=True)
#     except TypeError:
#         # missing_ok argument only 
#         # added since python 3.8
#         try:
#             file.unlink()
#         except FileNotFoundError:
#             pass


@task(help={'check': "Checks if source is formatted without applying changes"})
def format(c, check=False):
    """
    Format code
    """
    python_dirs_string = " ".join(PYTHON_DIRS)

    # Run autoflake
    autoflake_options = [
        "--check" if check else "--in-place",
        "--ignore-init-module-imports",
        "--recursive",
        "--remove-all-unused-imports",
    ] 
    c.run("autoflake {} {}".format(" ".join(autoflake_options), python_dirs_string))
    
    # Run yapf
    yapf_options = "--recursive {}".format("--diff" if check else "--in-place")
    c.run("yapf {} {}".format(yapf_options, python_dirs_string))
    
    # Run isort
    isort_options = [
        "--check-only" if check else "",
        "--combine-as",
        "--force-grid-wrap=0",
        "--line-width 79", # PEP 8 says 79.
        "--multi-line=3",
        "--trailing-comma",
    ]
    c.run("isort {} {}".format(" ".join(isort_options), python_dirs_string))

    # Run black
    black_options = [
        "--check" if check else "",
        "--line-length 79",
    ]
    c.run("black {} {}".format(" ".join(black_options), python_dirs_string))

    # Run vulture
    vulture_options = [
        "--min-confidence 70"
    ]
    c.run("vulture {} {}".format(" ".join(vulture_options), python_dirs_string))


@task
def lint_flake8(c):
    """
    Lint code with flake8
    """
    c.run("flake8 {} --count --select=E901,E999,F821,F822,F823 --show-source --statistics".format(" ".join(PYTHON_DIRS)))


@task
def lint_pylint(c):
    """
    Lint code with pylint
    """
    c.run("pylint {}".format(" ".join(PYTHON_DIRS)))


@task(lint_flake8) # , lint_pylint)
def lint(c):
    """
    Run all linting
    """
    pass


@task
def test(c):
    """
    Run tests
    """
    pty = platform.system() == 'Linux'
    c.run("pytest", pty=pty)


@task
def clean_build(c):
    """
    Clean up files from package building
    """
    c.run("rm -fr build/")
    c.run("rm -fr dist/")
    c.run("rm -fr .eggs/")
    c.run("find . -name '*.egg-info' -exec rm -fr {} +")
    c.run("find . -name '*.egg' -exec rm -f {} +")


@task
def clean_python(c):
    """
    Clean up python file artifacts
    """
    c.run("find . -name '*.pyc' -exec rm -f {} +")
    c.run("find . -name '*.pyo' -exec rm -f {} +")
    c.run("find . -name '*~' -exec rm -f {} +")
    c.run("find . -name '__pycache__' -exec rm -fr {} +")


@task(pre=[clean_build, clean_python])
def clean(c):
    """
    Runs all clean sub-tasks
    """
    pass


@task(clean)
def dist(c):
    """
    Build source and wheel packages
    """
    c.run("python setup.py sdist")
    c.run("python setup.py bdist_wheel")

"""
Tasks for maintaining the project.

Execute 'invoke --list' for guidance on using Invoke
"""
import shutil
import platform

from invoke import task
from pathlib import Path


ROOT_DIR = Path(__file__).parent
SETUP_FILE = ROOT_DIR.joinpath("setup.py")
TEST_DIR = ROOT_DIR.joinpath("tests")
SOURCE_DIR = ROOT_DIR.joinpath("spikex")
PYTHON_DIRS = [str(d) for d in (SOURCE_DIR, TEST_DIR)]


# def _delete_file(file):
#     try:
#         file.unlink(missing_ok=True)
#     except TypeError:
#         # missing_ok argument only 
#         # added since python 3.8
#         try:
#             file.unlink()
#         except FileNotFoundError:
#             pass


@task(help={'check': "Checks if source is formatted without applying changes"})
def format(c, check=False):
    """
    Format code
    """
    python_dirs_string = " ".join(PYTHON_DIRS)

    # Run autoflake
    autoflake_options = [
        "--check" if check else "--in-place",
        "--ignore-init-module-imports",
        "--recursive",
        "--remove-all-unused-imports",
    ] 
    c.run("autoflake {} {}".format(" ".join(autoflake_options), python_dirs_string))
    
    # Run yapf
    yapf_options = "--recursive {}".format("--diff" if check else "--in-place")
    c.run("yapf {} {}".format(yapf_options, python_dirs_string))
    
    # Run isort
    isort_options = [
        "--check-only" if check else "",
        "--combine-as",
        "--force-grid-wrap=0",
        "--line-width 79", # PEP 8 says 79.
        "--multi-line=3",
        "--trailing-comma",
    ]
    c.run("isort {} {}".format(" ".join(isort_options), python_dirs_string))

    # Run black
    black_options = [
        "--check" if check else "",
        "--line-length 79",
    ]
    c.run("black {} {}".format(" ".join(black_options), python_dirs_string))

    # Run vulture
    vulture_options = [
        "--min-confidence 70"
    ]
    c.run("vulture {} {}".format(" ".join(vulture_options), python_dirs_string))


@task
def lint_flake8(c):
    """
    Lint code with flake8
    """
    c.run("flake8 {} --count --select=E901,E999,F821,F822,F823 --show-source --statistics".format(" ".join(PYTHON_DIRS)))


@task
def lint_pylint(c):
    """
    Lint code with pylint
    """
    c.run("pylint {}".format(" ".join(PYTHON_DIRS)))


@task(lint_flake8) # , lint_pylint)
def lint(c):
    """
    Run all linting
    """
    pass


@task
def test(c):
    """
    Run tests
    """
    pty = platform.system() == 'Linux'
    c.run("pytest", pty=pty)


@task
def clean_build(c):
    """
    Clean up files from package building
    """
    c.run("rm -fr build/")
    c.run("rm -fr dist/")
    c.run("rm -fr .eggs/")
    c.run("find . -name '*.egg-info' -exec rm -fr {} +")
    c.run("find . -name '*.egg' -exec rm -f {} +")


@task
def clean_python(c):
    """
    Clean up python file artifacts
    """
    c.run("find . -name '*.pyc' -exec rm -f {} +")
    c.run("find . -name '*.pyo' -exec rm -f {} +")
    c.run("find . -name '*~' -exec rm -f {} +")
    c.run("find . -name '__pycache__' -exec rm -fr {} +")


@task(pre=[clean_build, clean_python])
def clean(c):
    """
    Runs all clean sub-tasks
    """
    pass


@task(clean)
def dist(c):
    """
    Build source and wheel packages
    """
    c.run("python setup.py sdist")
    c.run("python setup.py bdist_wheel")

Tasks for maintaining the project.  Execute 'invoke --list' for guidance on using Invoke # def _delete_file(file): #     try: #         file.unlink(missing_ok=True) #     except TypeError: #         # missing_ok argument only #         # added since python 3.8 #         try: #             file.unlink() #         except FileNotFoundError: #             pass Format code # Run autoflake # Run yapf # Run isort # PEP 8 says 79. # Run black # Run vulture Lint code with flake8 Lint code with pylint # , lint_pylint) Run all linting Run tests Clean up files from package building Clean up python file artifacts Runs all clean sub-tasks Build source and wheel packages