from __future__ import annotations

import logging
import os
import subprocess
import sys
from dataclasses import dataclass, field
from typing import TextIO, TYPE_CHECKING

import jinja2

if TYPE_CHECKING:
    from .ormatic import ORMatic

logger = logging.getLogger(__name__)


@dataclass
class SQLAlchemyGenerator:
    """
    A class for generating SQLAlchemy declarative mappings from ORMatic models.
    This class writes the tables generated by ORMatic to a file that serves as an SQL database interface.
    Uses Jinja2 templates for code generation.
    """

    ormatic: ORMatic
    """
    The ORMatic instance that created this SQLAlchemyGenerator.
    """

    env: jinja2.Environment = field(init=False, default=None)
    """
    The environment to use with jinja2.
    """

    def __post_init__(self):
        template_dir = os.path.join(os.path.dirname(__file__), "templates")
        self.env = jinja2.Environment(
            loader=jinja2.FileSystemLoader(template_dir),
            trim_blocks=True,
            lstrip_blocks=True,
        )

    def to_sqlalchemy_file(self, file: TextIO):
        """
        Generate a Python file with SQLAlchemy declarative mappings from the ORMatic models.

        :param file: The file to write to
        """
        # Load the template
        template = self.env.get_template("sqlalchemy_model.py.jinja")

        # Render the template
        output = template.render(
            ormatic=self.ormatic,
        )

        # Write the output to the file
        file.write(output)

        # format the output with black
        command = [sys.executable, "-m", "black", str(file.name)]
        subprocess.run(command, capture_output=True, text=True, check=True)
