import os

from lutris.util.log import logger


class RetroConfig:
    value_map = {"true": True, "false": False, "": None}

    def __init__(self, config_path):
        if not config_path:
            raise ValueError("Config path is mandatory")
        self.config_path = config_path
        self._config = []

    @property
    def config(self):
        """Lazy loading of the RetroArch config"""
        if self._config:
            return self._config
        try:
            self.load_config()
            return self._config
        except UnicodeDecodeError:
            logger.error(
                "The Retroarch config in %s could not be read because of character encoding issues", self.config_path
            )
            return []

    def load_config(self):
        """Load the configuration from file"""
        self._config = []
        if not os.path.isfile(self.config_path):
            raise OSError("Specified config file {} does not exist".format(self.config_path))
        with open(self.config_path, "r", encoding="utf-8") as config_file:
            for line in config_file.readlines():
                if not line:
                    continue
                line = line.strip()
                if line == "" or line.startswith("#"):
                    continue
                if "=" in line:
                    key, value = line.split("=", 1)
                    key = key.strip()
                    value = value.strip().strip('"')
                    if not key or not value:
                        continue
                    self._config.append((key, value))

    def save(self):
        with open(self.config_path, "w", encoding="utf-8") as config_file:
            for key, value in self.config:
                config_file.write('{} = "{}"\n'.format(key, value))

    def serialize_value(self, value):
        for k, v in self.value_map.items():
            if value is v:
                return k
        return value

    def deserialize_value(self, value):
        for k, v in self.value_map.items():
            if value == k:
                return v
        return value

    def __getitem__(self, key):
        for k, value in self.config:
            if key == k:
                return self.deserialize_value(value)

    def __setitem__(self, key, value):
        for index, conf in enumerate(self.config):
            if key == conf[0]:
                # self.config is read-only
                self._config[index] = (key, self.serialize_value(value))
                return
        self._config.append((key, self.serialize_value(value)))

    def keys(self):
        return [key for (key, _value) in self.config]
