from .src import *
from .get_full_confas import *
from abstract_utilities import os, write_to_file as _write_to_file, \
                 read_from_file as _read_from_file, \
                 make_dirs as _make_dirs, \
                 collect_globs as _collect_globs

class SingletonMeta(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]


class PathManager(metaclass=SingletonMeta):

    def __init__(self, *args, **kwargs):
        domain = kwargs.get('domain')

        if not hasattr(self, 'initialized') \
            or self.initialized is False \
            or (hasattr(self, 'domain') and domain != self.domain):

            self.initialized = True

            # Store remote/local login params
            self.pass_values = get_user_pass_host_key(**kwargs)

            # Start building internal paths
            self.parent_directory = kwargs.get('directory')
            self.parent_index_path = os.path.join(self.parent_directory,'index.conf')
            self.domain = self.extract_domain(**kwargs)

            self.filename, ext = os.path.splitext(self.domain)
            self.ext = ext.replace('.', '')

            self.root_content_dir = f'/var/www/sites/{self.filename}/{self.ext}/html/'
            self.root_content_path = os.path.join(self.parent_directory,'index.html')
            self.back_path = os.path.join(self.parent_directory,'index.conf.bak')

            # Build dirs
            self.main_dir = os.path.join(self.parent_directory, 'main')
            self.make_dirs(self.main_dir)

            self.pointers_dir = os.path.join(self.parent_directory, 'pointers')
            self.make_dirs(self.pointers_dir)

            self.endpoints_dir = os.path.join(self.parent_directory, 'endpoints')
            self.make_dirs(self.endpoints_dir)

            # File paths
            self.noncannonical_redirect_path = os.path.join(self.main_dir, 'noncannonical-redirect.conf')
            self.server_name_path = os.path.join(self.main_dir, 'server_name.conf')
            self.main_ssl_path = os.path.join(self.main_dir, 'ssl.conf')
            self.main_root_path = os.path.join(self.main_dir, 'root.conf')
            self.main_index_path = os.path.join(self.main_dir, 'index.conf')
            self.pointers_index_path = os.path.join(self.pointers_dir, "index.conf")
            self.pointers_main_path = os.path.join(self.pointers_dir, "main.conf")


    # ----------------------------------------------------------------------
    # SAFE WRAPPERS WITH CORRECT KWARG MERGING
    # ----------------------------------------------------------------------

    def _merge_kwargs(self, nu_kwargs: dict, **extra):
        """Always produce predictable kwargs for underlying functions."""
        merged = {**self.pass_values}     # remote/local info
        merged.update(nu_kwargs)          # user overrides
        merged.update(extra)              # required explicit arguments
        return merged


    def read_from_file(self, path, *args, **nu_kwargs):
        merged = self._merge_kwargs(nu_kwargs, path=path)
        return _read_from_file(*args, **merged)


    def write_to_file(self, contents, file_path, *args, **nu_kwargs):
        merged = self._merge_kwargs(nu_kwargs, contents=contents, file_path=file_path)
        print(merged)
        return _write_to_file(*args, **merged)


    def collect_globs(self, pattern, *args, **nu_kwargs):
        merged = self._merge_kwargs(nu_kwargs)
        return _collect_globs(pattern, *args, **merged).get('files')


    def make_dirs(self, path, *args, **nu_kwargs):
        merged = self._merge_kwargs(nu_kwargs, path=path)
        return _make_dirs(*args, **merged)


    # ----------------------------------------------------------------------
    # REMAINING HELPERS
    # ----------------------------------------------------------------------

    def get_initial_conf_and_domain(self):
        files = collect_globs(self.parent_directory, depth=1, file_type='f')
        files = [f for f in files if f and f.endswith('.conf')]
        for file in files:
            self.init_conf_file = file
            self.full_conf = get_full_confs(file_path=file, **self.pass_values)
            self.domain = self.full_conf.split('server_name ')[1].split(' www.')[0]
            if self.domain:
                break
        return self.domain

    def extract_domain(self, **kwargs):
        self.domain = kwargs.get('domain')
        if not self.domain:
            self.get_initial_conf_and_domain()
        return self.domain

    def uninitialize(self):
        self.initialized = False
def get_path_mgr(*args,**kwargs):
    return PathManager(*args,**kwargs)
def write_to_file(contents,file_path,*args,**kwargs):
    path_mgr = get_path_mgr(*args,**kwargs)
    return path_mgr.write_to_file(contents,file_path,**kwargs)
def read_from_file(file_path,*args,**kwargs):
    path_mgr = get_path_mgr(*args,**kwargs)
    return path_mgr.read_from_file(file_path,**kwargs)
def make_dirs(path,*args,**kwargs):
    path_mgr = get_path_mgr(*args,**kwargs)
    return path_mgr.make_dirs(path,**kwargs)
##def collect_globs(*args,**kwargs):
##    print('collect_globs')
##    path_mgr = get_path_mgr(*args,**kwargs)
##    return path_mgr.collect_globs(*args,**kwargs)
