# Copyright (C) 2018, 2019, 2020, 2021 The Meme Factory, Inc.
# http://www.karlpinc.com/

# This file is part of PGWUI_Server.
#
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License
# as published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License along with this program.  If not, see
# <http://www.gnu.org/licenses/>.
#

# Karl O. Pinc <kop@karlpinc.com>

'''Exceptions for PGWUI_Common, shared by all PGWUI components
'''

from pgwui_core import exceptions as core_ex
from pgwui_core.exceptions import (  # noqa: F401
    PGWUIError,
    UploadError,
    SetupError,
)
from . import constants


class Info(core_ex.UploadError):
    '''Informational exceptions
    '''
    pass


class MenuPageInRoutes(Info):
    def __init__(self):
        super().__init__(
            'The pgwui_menu in the pgwui.routes setting is ignored '
            'and the pgwui.menu_page setting used instead')


class BadHMACError(SetupError):
    pass


class NoHMACError(BadHMACError):
    def __init__(self):
        super().__init__('Missing session.secret configuration')


class HMACLengthError(BadHMACError):
    def __init__(self):
        super().__init__(
            'The session.secret value is not {} characters in length'
            .format(constants.HMAC_LEN))


class UnknownSettingKeyError(SetupError):
    def __init__(self, key):
        super().__init__('Unknown PGWUI setting: {}'.format(key))


class MissingSettingError(SetupError):
    def __init__(self, key):
        super().__init__('Missing PGWUI setting: {}'.format(key))


class BadPageTypeError(SetupError):
    def __init__(self, key, val):
        super().__init__(f'Bad {key} setting ({val})')


class BadPageSourceError(SetupError):
    def __init__(self, msg):
        super().__init__(msg)


class BadURLSourceError(BadPageSourceError):
    def __init__(self, key, val):
        super().__init__(
            f'Bad {key} setting for the "URL" type, ({val}) '
            'does not look like an URL')


class BadFileSourceError(BadPageSourceError):
    def __init__(self, key, val):
        super().__init__(
            f'Bad {key} setting for a "file" type, ({val}) '
            'does not look like a file system path beginning with "/"')


class BadFileURLPathError(BadPageSourceError):
    def __init__(self, key, val):
        super().__init__(
            f'Bad {key} setting for a "file" type, ({val}) '
            'does not look like a "path" component of an URL '
            'that begins with "/"')


class BadRouteSourceError(BadPageSourceError):
    def __init__(self, key, val):
        super().__init__(
            f'Bad {key} setting for a "route" type, ({val}) '
            'does not look like a Pyramid route name')


class BadAssetSourceError(BadPageSourceError):
    def __init__(self, key, val):
        super().__init__(
            f'Bad {key} setting for an "asset" type, ({val}) '
            'does not look like a Pyramid asset specification')


class NotBooleanSettingError(SetupError):
    def __init__(self, key, value):
        super().__init__(
            f'Bad value ({value}) for the {key} setting',
            'The "{}" PGWUI setting must be "True" or "False"'
            .format(key))


class NotBooleanChoiceSettingError(SetupError):
    def __init__(self, key, value):
        super().__init__(
            f'Bad value ({value}) for the {key} setting',
            (f'The "{key}" PGWUI setting must be one of: '
             '"yes-always", "choice-yes", "choice-no", "no-never"'))


class BadAssetOverrideError(SetupError):
    def __init__(self, asset, new_asset, exp):
        super().__init__(
            f'The asset ({asset}) cannot be overridden with ({new_asset}):'
            f' {exp}')


class BadSettingError(SetupError):
    def __init__(self, exp):
        super().__init__(
            f'Bad settings caused an error: {exp}'
            '\nHint: Overriding non-existant assets can cause this problem')


class BadPathError(SetupError):
    pass


class BadRouteError(BadPathError):
    def __init__(self, page, ex):
        super().__init__(
            page, ex,
            f'The "pgwui:{page}:source" configuration setting refers to '
            'a route that does not exist')


class BadAssetError(BadPathError):
    def __init__(self, page, ex):
        super().__init__(
            page, ex,
            f'The "pgwui:{page}:source" configuration setting refers to '
            'an asset that does not exist')


class ViewError(SetupError):
    pass


class BadPageError(ViewError):
    def __init__(self, page, ex, msg):
        self.page = page
        self.ex = ex
        super().__init__(msg)


class BadPageFileNotFoundError(BadPageError):
    def __init__(self, page, ex):
        super().__init__(
            page, ex,
            f'The "pgwui:{page}:source" configuration setting refers to '
            f'a file ({ex.filename}) that does not exist')


class BadPageFilePermissionError(BadPageError):
    def __init__(self, page, ex):
        super().__init__(
            page, ex,
            f'The "pgwui:{page}:source" configuration setting refers to '
            f'a file ({ex.filename}) which cannot be read due to file '
            'system permissions')


class BadPageIsADirectoryError(BadPageError):
    def __init__(self, page, ex):
        super().__init__(
            page, ex,
            f'The "pgwui:{page}:source" configuration setting refers to '
            f'a directory ({ex.filename}), not a file')
