import json
import os
from io import StringIO

from cpbox.tool import cls
from cpbox.tool import file


class YAMLInitializer(cls.Singleton):

    def _init_once(self):
        from ruamel.yaml import YAML
        self.yaml = YAML(typ='rt')
        self.yaml.indent(mapping=2, sequence=4, offset=2)
        self.yaml.allow_unicode = True
        self.yaml.sort_keys = False
        self.yaml.default_flow_style = False
        self.yaml.default_style = None


yaml = YAMLInitializer().yaml


def pyaml(data) -> str:
    stream = StringIO()
    yaml.dump(data, stream=stream)
    return stream.getvalue()


def pjson(data):
    return json.dumps(data, ensure_ascii=False, indent=2)


def load_yaml_file(fn, fallback=None):
    if not os.path.isfile(fn):
        return fallback
    with open(fn, 'r', encoding='utf-8') as input_file:
        data = yaml.load(input_file)
    return data if data is not None else fallback


def dump_yaml_file(fn, data):
    file.ensure_dir_for_file(str(fn))
    with open(fn, 'w', encoding='utf-8') as outfile:
        yaml.dump(data, outfile)


def load_json_file(fn, fallback=None):
    if not os.path.isfile(fn):
        return fallback
    try:
        with open(fn, 'r', encoding='utf-8') as input_file:
            data = json.load(input_file)
        return data if data is not None else fallback
    except Exception:
        return fallback


def dump_json_file(fn, data):
    file.ensure_dir_for_file(str(fn))
    with open(fn, 'w', encoding='utf-8') as output_file:
        json.dump(data, output_file, ensure_ascii=False, indent=2)
