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

# This file is part of PGWUI_Copy.
#
# 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>

import markupsafe

from pgwui_copy import utils
from pgwui_core import exceptions as core_ex
# Errors without data files and line numbers
from pgwui_common.exceptions import SetupError as Error


# Setup errors
class NoSchemaError(Error):
    def __init__(self, e, descr='', detail=''):
        super().__init__(e, descr, detail)


class LiveDBTargetError(Error):
    def __init__(self, e, descr='', detail=''):
        super().__init__(e, descr, detail)


class NonAdminUserError(Error):
    def __init__(self, e, descr='', detail=''):
        super().__init__(e, descr, detail)


class NoFromDBError(Error):
    def __init__(self, e, descr='', detail=''):
        super().__init__(e, descr, detail)


class NoToDBError(Error):
    def __init__(self, e, descr='', detail=''):
        super().__init__(e, descr, detail)


class SameDBError(Error):
    def __init__(self, e, descr='', detail=''):
        super().__init__(e, descr, detail)


class InvalidSchemaError(Error):
    def __init__(self, e, descr='', detail=''):
        super().__init__(e, descr, detail)


class CopyToDefaultError(Error):
    def __init__(self, e, descr='', detail=''):
        super().__init__(e, descr, detail)


class SchemaExistsError(Error):
    def __init__(self, e, descr='', detail=''):
        super().__init__(e, descr, detail)


class InconsistentDBError(Error):
    def __init__(self, e, descr='', detail=''):
        super().__init__(e, descr, detail)


class SchemaDroppedError(InconsistentDBError):
    def __init__(self, e, descr='', detail=''):
        super().__init__(e, descr, detail)


class SchemaCopiedError(InconsistentDBError):
    def __init__(self, e, descr='', detail=''):
        super().__init__(e, descr, detail)


class CopyCommandError(Error):
    def __init__(self, e, descr='', detail=''):
        super().__init__(e, descr, detail)


# Errors copying using pg_dump/pg_restore.

class CopyOSError(CopyCommandError):
    '''The copy of the schema failed with an OSError.'''
    def __init__(self, e, ex, descr='', detail=''):
        detail = ('<p>The operating system reports: {0}</p>'
                  .format(markupsafe.escape(ex.strerror)))
        super().__init__(e, descr, detail)


class PGDumpOSError(CopyOSError):
    def __init__(self, e, ex, descr=''):
        super().__init__(e, ex, descr)


class PGRestoreOSError(CopyOSError):
    def __init__(self, e, ex, descr=''):
        super().__init__(e, ex, descr)


class CopyProcessError(CopyCommandError):
    '''The process which copies the schema failed.'''
    def __init__(self, e, retcode, stderr=''):
        descr_ish = (
            '<p>The process reports: {0}</p>'
            .format(markupsafe.escape(utils.translate_retcode(retcode))))
        detail = f'<p>The error messages are:</p><pre>\n{stderr}</pre>'
        super().__init__(e, detail=f'{descr_ish}{detail}')


class PGDumpError(CopyProcessError):
    def __init__(self, e, retcode, stderr=''):
        super().__init__(e, retcode, stderr)


class PGRestoreError(CopyProcessError):
    def __init__(self, e, retcode, stderr=''):
        super().__init__(e, retcode, stderr)


# Database statement execution errors

class DropSchemaError(core_ex.DBError):
    def __init__(self, pgexc, schema, db):
        '''
        pgexc  The psycopg2 exception object
        '''
        super().__init__(
            pgexc, 'drop the ({0}) schema in the ({1}) db'.format(schema, db))


class VacuumFullError(core_ex.DBError):
    def __init__(self, pgexc, db):
        '''
        pgexc  The psycopg2 exception object
        '''
        super().__init__(
            pgexc, 'VACUUM FULL the ({0}) db'.format(db))


class VacuumAnalyzeError(core_ex.DBError):
    def __init__(self, pgexc, db):
        '''
        pgexc  The psycopg2 exception object
        '''
        super().__init__(
            pgexc, 'VACUUM ANALYZE the ({0}) db'.format(db))
