from __future__ import annotations

import contextlib
import os
import subprocess
from pathlib import Path
from types import TracebackType

import pygit2

from pygitweb.config import settings
from pygitweb.tasks import create_board_for_project


class Project:
    """
    Plugin API: Project - the root class for a project which is always a directory, and _may_ contain a git repository.
    """

    def __init__(
        self,
        path: os.PathLike[str] | str,
        remote_url: str | None = None,
        create_task_board: bool = False,
        do_maintenance: bool = False,
    ) -> None:
        self.path: str = str(Path(path))
        self.remote_url: str | None = remote_url
        os.makedirs(self.path)
        if self.remote_url:
            pygit2.clone_repository(self.remote_url, self.path, bare=True)
        else:
            pygit2.init_repository(self.path, bare=True)
        self.repo: pygit2.Repository = pygit2.Repository(self.path)
        if create_task_board:
            create_board_for_project(Path(self.path).name, name="Tasks", description="")
        if do_maintenance:
            with contextlib.suppress(subprocess.SubprocessError, FileNotFoundError):
                subprocess.run(
                    [settings.GIT, "-C", self.path, "maintenance", "start"],
                    capture_output=True,
                    timeout=60,
                )

    def __enter__(self) -> Project:
        return self

    def __exit__(
        self,
        exc_type: type[BaseException] | None,
        exc_value: BaseException | None,
        traceback: TracebackType | None,
    ) -> None:
        self.repo.free()

    def __del__(self) -> None:
        self.repo.free()

    @classmethod
    def form_content(cls) -> str:
        return (
            '<label class="form-label" for="pull_from_remote">Pull from remote</label>'
            '<input type="url" class="form-control" id="pull_from_remote" name="pull_from_remote" '
            'placeholder="https://example.com/repo.git or ssh://git@host/repo.git or git://host/repo.git">'
            '<small class="form-hint">Optional. Use an <code>ssh://</code>, <code>git://</code>, '
            "or <code>https://</code> URL to clone an existing repository.</small>"
        )