import json
from typing import Optional
from xml.sax import saxutils

from ._util import (
    _TYPES_MAP,
    ARRAY,
)


class Key(object):
    def __init__(
        self,
        name: str,
        type: int,
        descr: str,
    ):
        self.name = name
        self.descr = descr
        self.type = type
        self.values = []

    def value(self) -> Optional[str]:
        return self.values[0] if self.values else None

    def add_value(self, value: str):
        self.values.append(value)
        return self

    def __str__(self):
        return json.dumps(
            {
                "name": self.name,
                "descr": self.descr,
                "type": _TYPES_MAP[self.type],
                "values": self.values,
            }
        )

    def __eq__(self, other):
        if not isinstance(other, Key):
            return False

        return (
                self.name == other.name and
                sorted(self.values) == sorted(other.values)
        )

    def __lt__(self, other):
        return self.name < other.name

    def write(self, out, level):
        out.write('%s<key' % ("\t" * level))
        if self.name is not None:
            out.write(' name=%s' % saxutils.quoteattr(self.name))
        if self.descr is not None:
            out.write(' descr=%s' % saxutils.quoteattr(self.descr))
        out.write('>\n')
        if self.values:
            level += 1
            type_str = _TYPES_MAP[self.type]
            if self.type == ARRAY:
                type_str = "string"
                out.write('%s<array>\n' % ("\t" * level))
                level += 1
            for val in self.values:
                out.write('{}<{}>{}</{}>\n'.format("\t" * level, type_str, saxutils.escape(val), type_str))
            if self.type == ARRAY:
                level -= 1
                out.write('%s</array>\n' % ("\t" * level))
            level -= 1
        out.write('%s</key>\n' % ("\t" * level))


