import os
from pathlib import Path
from collections import defaultdict
from fastcore.foundation import L  # type: ignore
from fastcore.basics import ifnone  # type: ignore
from nbdev.config import write_cells  # type: ignore


class DbtMaker:
    "Helper class to create a dbt file from notebook source cells"

    def __init__(self, dest, nb_path):
        self.dest_dbt_filepath = Path(dest)
        self.dest_dirname = Path(os.path.dirname(dest))
        self.dest_dirname.mkdir(parents=True, exist_ok=True)
        self.dest_nb = os.path.relpath(Path(nb_path), self.dest_dirname)
        self.hdr = f"-- %% {self.dest_nb}"

    def make(self, cell):
        with self.dest_dbt_filepath.open("w", encoding="utf-8") as f:
            f.write(f"-- AUTOGENERATED! DO NOT EDIT! File to edit: {self.dest_nb}.")
            cells = L([cell])
            write_cells(cells, self.hdr, f)
            f.write("\n")


class ExportDBTProc:
    """
    A processor which exports dbt code to a dbt file. Each cell with this directive will be exported as a separate file.

    Args:
    - The file to write the dbt code to.

    Example usage:
    #|export_dbt models/my_model.sql
    """

    def begin(self):
        self.file_content = defaultdict(L)

    # exp_to_filepath is the args passed to the export_dbt directive
    def _export_dbt_(self, cell, exp_to_filepath=None):
        if exp_to_filepath is None:
            raise ValueError(
                "Please provide a filepath to export the dbt code to (i.e. #|export_dbt path/to/dbt_file.sql)."
            )
        self.file_content[exp_to_filepath] = cell
