import json
from collections import defaultdict

from paramtools import utils


class ParamToolsError(Exception):
    pass


class ParameterUpdateException(ParamToolsError):
    pass


class SparseValueObjectsException(ParamToolsError):
    pass


class ValidationError(ParamToolsError):
    def __init__(self, messages, labels):
        self.messages = messages
        self.labels = labels
        error_msg = defaultdict(dict)
        for error_type, msgs in self.messages.items():
            for param, msg in msgs.items():
                error_msg[error_type][param] = utils.ravel(msg)
        super().__init__(json.dumps(error_msg, indent=4))


class InconsistentLabelsException(ParamToolsError):
    pass


collision_list = [
    "_data",
    "_errors",
    "_warnings",
    "select_eq",
    "select_gt",
    "_adjust",
    "_numpy_type",
    "_parse_errors",
    "_resolve_order",
    "_search_trees",
    "_schema",
    "_set_state",
    "_state",
    "_stateless_label_grid",
    "_update_param",
    "_validator_schema",
    "_defaults_schema",
    "operators",
    "adjust",
    "array_first",
    "clear_state",
    "defaults",
    "dump",
    "items",
    "keys",
    "label_grid",
    "label_validators",
    "errors",
    "warnings",
    "field_map",
    "from_array",
    "read_params",
    "set_state",
    "specification",
    "sort_values",
    "to_array",
    "validation_error",
    "view_state",
    "extend",
    "extend_func",
    "uses_extend_func",
    "label_to_extend",
    "get_index_rate",
    "index_rates",
    "to_dict",
    "_parse_validation_messages",
]


class ParameterNameCollisionException(ParamToolsError):
    pass
