# Copyright 2019 Canonical Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
#     Unless required by applicable law or agreed to in writing, software
#     distributed under the License is distributed on an "AS IS" BASIS,
#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#     See the License for the specific language governing permissions and
#     limitations under the License.


class JujuCharmNotFound(Exception):
    """The Charm can't be found or is not readable."""


class JujuApplicationExists(Exception):
    """The Application already exists."""


class N2VCPrimitiveExecutionFailed(Exception):
    """Something failed while attempting to execute a primitive."""


class NetworkServiceDoesNotExist(Exception):
    """The Network Service being acted against does not exist."""


class PrimitiveDoesNotExist(Exception):
    """The Primitive being executed does not exist."""


class NoRouteToHost(Exception):
    """There was no route to the specified host."""


class AuthenticationFailed(Exception):
    """The authentication for the specified user failed."""


class MethodNotImplemented(Exception):
    """The method is not implemented."""


class N2VCException(Exception):
    """
    N2VC exception base class
    """

    def __init__(self, message: str = ""):
        Exception.__init__(self, message)
        self.message = message

    def __str__(self):
        return self.message

    def __repr__(self):
        return "{}({})".format(type(self), self.message)


class N2VCBadArgumentsException(N2VCException):
    """
    Bad argument values exception
    """

    def __init__(self, message: str = "", bad_args: list = None):
        N2VCException.__init__(self, message=message)
        self.bad_args = bad_args

    def __str__(self):
        return "<{}> Bad arguments: {} -> {}".format(
            type(self), super().__str__(), self.bad_args
        )


class N2VCConnectionException(N2VCException):
    """
    Error connecting to VCA
    """

    def __init__(self, message: str = "", url: str = None):
        N2VCException.__init__(self, message=message)
        self.url = url

    def __str__(self):
        return "<{}> Connection to {} failed: {}".format(
            type(self), self.url, super().__str__()
        )


class N2VCTimeoutException(N2VCException):
    """
    Timeout
    """

    def __init__(self, message: str = "", timeout: str = ""):
        N2VCException.__init__(self, message=message)
        self.timeout = timeout

    def __str__(self):
        return "<{}> {} timeout: {}".format(type(self), self.timeout, super().__str__())


class N2VCExecutionException(N2VCException):
    """
    Error executing primitive
    """

    def __init__(self, message: str = "", primitive_name: str = ""):
        N2VCException.__init__(self, message=message)
        self.primitive_name = primitive_name

    def __str__(self):
        return "<{}> Error executing primitive {} failed: {}".format(
            type(self), self.primitive_name, super().__str__()
        )


class N2VCInvalidCertificate(N2VCException):
    """
    Invalid certificate
    """

    def __init__(self, message: str = ""):
        N2VCException.__init__(self, message=message)

    def __str__(self):
        return "<{}> Invalid certificate: {}".format(type(self), super().__str__())


class N2VCNotFound(N2VCException):
    """
    Not found
    """

    def __init__(self, message: str = ""):
        N2VCException.__init__(self, message=message)

    def __str__(self):
        return "<{}> Not found: {}".format(type(self), super().__str__())


class K8sException(Exception):
    """
    K8s exception
    """

    def __init__(self, message: str):
        Exception.__init__(self, message)
        self._message = message

    def __str__(self):
        return self._message

    def __repr__(self):
        return self._message
