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>"
		)