from hed.errors.error_types import ErrorContext


class HedExceptions:
    GENERIC_ERROR = 'GENERIC_ERROR'
    # A list of all exceptions that can be generated by the hedtools.
    FILE_NOT_FOUND = 'fileNotFound'
    BAD_PARAMETERS = 'badParameters'
    CANNOT_PARSE_XML = 'cannotParseXML'
    CANNOT_PARSE_JSON = 'cannotParseJson'
    INVALID_EXTENSION = 'invalidExtension'

    INVALID_DATAFRAME = 'INVALID_DATAFRAME'
    INVALID_FILE_FORMAT = 'INVALID_FILE_FORMAT'
    # These are actual schema issues, not that the file cannot be found or parsed
    SCHEMA_HEADER_MISSING = 'HED_SCHEMA_HEADER_INVALID'
    HED_SCHEMA_HEADER_INVALID = 'HED_SCHEMA_HEADER_INVALID'

    SCHEMA_LIBRARY_INVALID = "SCHEMA_LIBRARY_INVALID"
    BAD_HED_LIBRARY_NAME = 'SCHEMA_LIBRARY_INVALID'
    BAD_WITH_STANDARD = "SCHEMA_LIBRARY_INVALID"
    BAD_WITH_STANDARD_VERSION = "SCHEMA_LIBRARY_INVALID"
    ROOTED_TAG_INVALID = "SCHEMA_LIBRARY_INVALID"
    ROOTED_TAG_HAS_PARENT = "SCHEMA_LIBRARY_INVALID"
    ROOTED_TAG_DOES_NOT_EXIST = "SCHEMA_LIBRARY_INVALID"
    IN_LIBRARY_IN_UNMERGED = "SCHEMA_LIBRARY_INVALID"

    HED_SCHEMA_VERSION_INVALID = 'HED_SCHEMA_VERSION_INVALID'
    SCHEMA_START_MISSING = 'HED_WIKI_SEPARATOR_INVALID'
    SCHEMA_END_INVALID = 'HED_WIKI_SEPARATOR_INVALID'
    HED_END_INVALID = 'HED_WIKI_SEPARATOR_INVALID'
    INVALID_SECTION_SEPARATOR = 'invalidSectionSeparator'

    # This issue will contain a list of lines with issues.
    HED_WIKI_DELIMITERS_INVALID = 'HED_WIKI_DELIMITERS_INVALID'
    HED_SCHEMA_NODE_NAME_INVALID = 'HED_SCHEMA_NODE_NAME_INVALID'

    SCHEMA_DUPLICATE_PREFIX = 'schemaDuplicatePrefix'
    BAD_COLUMN_NAMES = 'BAD_COLUMN_NAMES'


class HedFileError(Exception):
    """Exception raised when a file cannot be parsed due to being malformed, file IO, etc."""
    def __init__(self, code, message, filename, issues=None):
        self.code = code
        self.message = message
        self.filename = filename
        self.issues = issues
        if self.issues is None:
            self.issues = [
                {'message': message,
                 ErrorContext.FILE_NAME: filename,
                 'code': code}
            ]
