# Path: i3configger/context.py
# def process(item: Iterable[Union[dict, partials.Partial]]) -> dict:
# def merge_all(item: Iterable[Union[dict, partials.Partial]]) -> dict:
# def merge(dst: dict, src: dict) -> dict:
# def prune(dst: dict, src: dict) -> dict:
# def resolve_variables(ctx: dict) -> dict:
# def _resolve_variable(key, ctx, path):
# def remove_variable_markers(ctx: dict) -> dict:
# def substitute(content: str, ctx: dict):
# 
# Path: i3configger/exc.py
# class I3configgerException(Exception):
# class BuildError(I3configgerException):
# class ConfigError(I3configgerException):
# class MessageError(I3configgerException):
# class PartialsError(I3configgerException):
# class ParseError(I3configgerException):
# class ContextError(I3configgerException):
# class UserError(I3configgerException):


import copy
import json
import logging
import os
import pprint
import shutil
from pathlib import Path
from i3configger import context, exc

def freeze(path, obj):
    path.write_text(json.dumps(obj, sort_keys=True, indent=2))
    log.debug(f"froze {pprint.pformat(obj)} to {path}")


def ensure_i3_configger_sanity():
    i3wmConfigPath = get_i3wm_config_path()
    partialsPath = i3wmConfigPath / I3configgerConfig.PARTIALS_NAME
    if not partialsPath.exists():
        log.info(f"create new config folder at {partialsPath}")
        partialsPath.mkdir()
        for candidate in [i3wmConfigPath / "config", Path("etc/i3/config")]:
            if candidate.exists():
                log.info(f"populate config with {candidate}")
                shutil.copy2(candidate, partialsPath / "config.conf")
    configPath = partialsPath / I3configgerConfig.CONFIG_NAME
    if not configPath.exists():
        log.info(f"create default configuration at {configPath}")
        freeze(configPath, DEFAULTS)


def get_i3wm_config_path():
    """Use same search order like i3 (no system stuff though).

    see: https://github.com/i3/i3/blob/4.13/libi3/get_config_path.c#L31
    """
    for candidate in CONFIG_CANDIDATES:
        if candidate.exists():
            return candidate

# Path: i3configger/context.py
# def process(item: Iterable[Union[dict, partials.Partial]]) -> dict:
# def merge_all(item: Iterable[Union[dict, partials.Partial]]) -> dict:
# def merge(dst: dict, src: dict) -> dict:
# def prune(dst: dict, src: dict) -> dict:
# def resolve_variables(ctx: dict) -> dict:
# def _resolve_variable(key, ctx, path):
# def remove_variable_markers(ctx: dict) -> dict:
# def substitute(content: str, ctx: dict):
# 
# Path: i3configger/exc.py
# class I3configgerException(Exception):
# class BuildError(I3configgerException):
# class ConfigError(I3configgerException):
# class MessageError(I3configgerException):
# class PartialsError(I3configgerException):
# class ParseError(I3configgerException):
# class ContextError(I3configgerException):
# class UserError(I3configgerException):


# Path: i3configger/config.py
import copy
import json
import logging
import os
import pprint
import shutil
from pathlib import Path
from i3configger import context, exc


def freeze(path, obj):
    path.write_text(json.dumps(obj, sort_keys=True, indent=2))
    log.debug(f"froze {pprint.pformat(obj)} to {path}")


def ensure_i3_configger_sanity():
    i3wmConfigPath = get_i3wm_config_path()
    partialsPath = i3wmConfigPath / I3configgerConfig.PARTIALS_NAME
    if not partialsPath.exists():
        log.info(f"create new config folder at {partialsPath}")
        partialsPath.mkdir()
        for candidate in [i3wmConfigPath / "config", Path("etc/i3/config")]:
            if candidate.exists():
                log.info(f"populate config with {candidate}")
                shutil.copy2(candidate, partialsPath / "config.conf")
    configPath = partialsPath / I3configgerConfig.CONFIG_NAME
    if not configPath.exists():
        log.info(f"create default configuration at {configPath}")
        freeze(configPath, DEFAULTS)


def get_i3wm_config_path():
    """Use same search order like i3 (no system stuff though).

    see: https://github.com/i3/i3/blob/4.13/libi3/get_config_path.c#L31
    """
    for candidate in CONFIG_CANDIDATES:
        if candidate.exists():
            return candidate

    raise exc.ConfigError(