# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

from libcloud.common.base import ConnectionUserAndKey, BaseDriver
from libcloud.backup.types import BackupTargetType

__all__ = [
    "BackupTarget",
    "BackupDriver",
    "BackupTargetJob",
    "BackupTargetRecoveryPoint",
]


class BackupTarget(object):
    """
    A backup target
    """

    def __init__(self, id, name, address, type, driver, extra=None):
        """
        :param id: Target id
        :type id: ``str``

        :param name: Name of the target
        :type name: ``str``

        :param address: Hostname, FQDN, IP, file path etc.
        :type address: ``str``

        :param type: Backup target type (Physical, Virtual, ...).
        :type type: :class:`.BackupTargetType`

        :param driver: BackupDriver instance.
        :type driver: :class:`.BackupDriver`

        :param extra: (optional) Extra attributes (driver specific).
        :type extra: ``dict``
        """
        self.id = str(id) if id else None
        self.name = name
        self.address = address
        self.type = type
        self.driver = driver
        self.extra = extra or {}

    def update(self, name=None, address=None, extra=None):
        return self.driver.update_target(
            target=self, name=name, address=address, extra=extra
        )

    def delete(self):
        return self.driver.delete_target(target=self)

    def _get_numeric_id(self):
        target_id = self.id

        if target_id.isdigit():
            target_id = int(target_id)

        return target_id

    def __repr__(self):
        return "<Target: id=%s, name=%s, address=%s" "type=%s, provider=%s ...>" % (
            self.id,
            self.name,
            self.address,
            self.type,
            self.driver.name,
        )


class BackupTargetJob(object):
    """
    A backup target job
    """

    def __init__(self, id, status, progress, target, driver, extra=None):
        """
        :param id: Job id
        :type id: ``str``

        :param status: Status of the job
        :type status: :class:`BackupTargetJobStatusType`

        :param progress: Progress of the job, as a percentage
        :type progress: ``int``

        :param target: BackupTarget instance.
        :type target: :class:`.BackupTarget`

        :param driver: BackupDriver instance.
        :type driver: :class:`.BackupDriver`

        :param extra: (optional) Extra attributes (driver specific).
        :type extra: ``dict``
        """
        self.id = str(id) if id else None
        self.status = status
        self.progress = progress
        self.target = target
        self.driver = driver
        self.extra = extra or {}

    def cancel(self):
        return self.driver.cancel_target_job(job=self)

    def suspend(self):
        return self.driver.suspend_target_job(job=self)

    def resume(self):
        return self.driver.resume_target_job(job=self)

    def __repr__(self):
        return "<Job: id=%s, status=%s, progress=%s" "target=%s, provider=%s ...>" % (
            self.id,
            self.status,
            self.progress,
            self.target.id,
            self.driver.name,
        )


class BackupTargetRecoveryPoint(object):
    """
    A backup target recovery point
    """

    def __init__(self, id, date, target, driver, extra=None):
        """
        :param id: Job id
        :type id: ``str``

        :param date: The date taken
        :type date: :class:`datetime.datetime`

        :param target: BackupTarget instance.
        :type target: :class:`.BackupTarget`

        :param driver: BackupDriver instance.
        :type driver: :class:`.BackupDriver`

        :param extra: (optional) Extra attributes (driver specific).
        :type extra: ``dict``
        """
        self.id = str(id) if id else None
        self.date = date
        self.target = target
        self.driver = driver
        self.extra = extra or {}

    def recover(self, path=None):
        """
        Recover this recovery point

        :param path: The part of the recovery point to recover (optional)
        :type  path: ``str``

        :rtype: Instance of :class:`.BackupTargetJob`
        """
        return self.driver.recover_target(
            target=self.target, recovery_point=self, path=path
        )

    def recover_to(self, recovery_target, path=None):
        """
        Recover this recovery point out of place

        :param recovery_target: Backup target with to recover the data to
        :type  recovery_target: Instance of :class:`.BackupTarget`

        :param path: The part of the recovery point to recover (optional)
        :type  path: ``str``

        :rtype: Instance of :class:`.BackupTargetJob`
        """
        return self.driver.recover_target_out_of_place(
            target=self.target,
            recovery_point=self,
            recovery_target=recovery_target,
            path=path,
        )

    def __repr__(self):
        return "<RecoveryPoint: id=%s, date=%s, " "target=%s, provider=%s ...>" % (
            self.id,
            self.date,
            self.target.id,
            self.driver.name,
        )


class BackupDriver(BaseDriver):
    """
    A base BackupDriver class to derive from

    This class is always subclassed by a specific driver.
    """

    connectionCls = ConnectionUserAndKey
    name = None
    website = None

    def __init__(self, key, secret=None, secure=True, host=None, port=None, **kwargs):
        """
        :param    key: API key or username to used (required)
        :type     key: ``str``

        :param    secret: Secret password to be used (required)
        :type     secret: ``str``

        :param    secure: Whether to use HTTPS or HTTP. Note: Some providers
                only support HTTPS, and it is on by default.
        :type     secure: ``bool``

        :param    host: Override hostname used for connections.
        :type     host: ``str``

        :param    port: Override port used for connections.
        :type     port: ``int``

        :return: ``None``
        """
        super(BackupDriver, self).__init__(
            key=key, secret=secret, secure=secure, host=host, port=port, **kwargs
        )

    def get_supported_target_types(self):
        """
        Get a list of backup target types this driver supports

        :return: ``list`` of :class:``BackupTargetType``
        """
        raise NotImplementedError(
            "get_supported_target_types not implemented for this driver"
        )

    def list_targets(self):
        """
        List all backuptargets

        :rtype: ``list`` of :class:`.BackupTarget`
        """
        raise NotImplementedError("list_targets not implemented for this driver")

    def create_target(self, name, address, type=BackupTargetType.VIRTUAL, extra=None):
        """
        Creates a new backup target

        :param name: Name of the target
        :type name: ``str``

        :param address: Hostname, FQDN, IP, file path etc.
        :type address: ``str``

        :param type: Backup target type (Physical, Virtual, ...).
        :type type: :class:`BackupTargetType`

        :param extra: (optional) Extra attributes (driver specific).
        :type extra: ``dict``

        :rtype: Instance of :class:`.BackupTarget`
        """
        raise NotImplementedError("create_target not implemented for this driver")

    def create_target_from_node(self, node, type=BackupTargetType.VIRTUAL, extra=None):
        """
        Creates a new backup target from an existing node.
        By default, this will use the first public IP of the node

        :param node: The Node to backup
        :type  node: ``Node``

        :param type: Backup target type (Physical, Virtual, ...).
        :type type: :class:`BackupTargetType`

        :param extra: (optional) Extra attributes (driver specific).
        :type extra: ``dict``

        :rtype: Instance of :class:`.BackupTarget`
        """
        return self.create_target(
            name=node.name, address=node.public_ips[0], type=type, extra=None
        )

    def create_target_from_storage_container(
        self, container, type=BackupTargetType.OBJECT, extra=None
    ):
        """
        Creates a new backup target from an existing storage container

        :param node: The Container to backup
        :type  node: ``Container``

        :param type: Backup target type (Physical, Virtual, ...).
        :type type: :class:`BackupTargetType`

        :param extra: (optional) Extra attributes (driver specific).
        :type extra: ``dict``

        :rtype: Instance of :class:`.BackupTarget`
        """
        return self.create_target(
            name=container.name, address=container.get_cdn_url(), type=type, extra=None
        )

    def update_target(self, target, name, address, extra):
        """
        Update the properties of a backup target

        :param target: Backup target to update
        :type  target: Instance of :class:`.BackupTarget`

        :param name: Name of the target
        :type name: ``str``

        :param address: Hostname, FQDN, IP, file path etc.
        :type address: ``str``

        :param extra: (optional) Extra attributes (driver specific).
        :type extra: ``dict``

        :rtype: Instance of :class:`.BackupTarget`
        """
        raise NotImplementedError("update_target not implemented for this driver")

    def delete_target(self, target):
        """
        Delete a backup target

        :param target: Backup target to delete
        :type  target: Instance of :class:`.BackupTarget`
        """
        raise NotImplementedError("delete_target not implemented for this driver")

    def list_recovery_points(self, target, start_date=None, end_date=None):
        """
        List the recovery points available for a target

        :param target: Backup target to delete
        :type  target: Instance of :class:`.BackupTarget`

        :param start_date: The start date to show jobs between (optional)
        :type  start_date: :class:`datetime.datetime`

        :param end_date: The end date to show jobs between (optional)
        :type  end_date: :class:`datetime.datetime``

        :rtype: ``list`` of :class:`.BackupTargetRecoveryPoint`
        """
        raise NotImplementedError(
            "list_recovery_points not implemented for this driver"
        )

    def recover_target(self, target, recovery_point, path=None):
        """
        Recover a backup target to a recovery point

        :param target: Backup target to delete
        :type  target: Instance of :class:`.BackupTarget`

        :param recovery_point: Backup target with the backup data
        :type  recovery_point: Instance of :class:`.BackupTarget`

        :param path: The part of the recovery point to recover (optional)
        :type  path: ``str``

        :rtype: Instance of :class:`.BackupTargetJob`
        """
        raise NotImplementedError("recover_target not implemented for this driver")

    def recover_target_out_of_place(
        self, target, recovery_point, recovery_target, path=None
    ):
        """
        Recover a backup target to a recovery point out-of-place

        :param target: Backup target with the backup data
        :type  target: Instance of :class:`.BackupTarget`

        :param recovery_point: Backup target with the backup data
        :type  recovery_point: Instance of :class:`.BackupTarget`

        :param recovery_target: Backup target with to recover the data to
        :type  recovery_target: Instance of :class:`.BackupTarget`

        :param path: The part of the recovery point to recover (optional)
        :type  path: ``str``

        :rtype: Instance of :class:`BackupTargetJob`
        """
        raise NotImplementedError(
            "recover_target_out_of_place not implemented for this driver"
        )

    def get_target_job(self, target, id):
        """
        Get a specific backup job by ID

        :param target: Backup target with the backup data
        :type  target: Instance of :class:`.BackupTarget`

        :param id: Backup target with the backup data
        :type  id: Instance of :class:`.BackupTarget`

        :rtype: :class:`BackupTargetJob`
        """
        jobs = self.list_target_jobs(target)
        return list(filter(lambda x: x.id == id, jobs))[0]

    def list_target_jobs(self, target):
        """
        List the backup jobs on a target

        :param target: Backup target with the backup data
        :type  target: Instance of :class:`.BackupTarget`

        :rtype: ``list`` of :class:`.BackupTargetJob`
        """
        raise NotImplementedError("list_target_jobs not implemented for this driver")

    def create_target_job(self, target, extra=None):
        """
        Create a new backup job on a target

        :param target: Backup target with the backup data
        :type  target: Instance of :class:`.BackupTarget`

        :param extra: (optional) Extra attributes (driver specific).
        :type extra: ``dict``

        :rtype: Instance of :class:`BackupTargetJob`
        """
        raise NotImplementedError("create_target_job not implemented for this driver")

    def resume_target_job(self, job):
        """
        Resume a suspended backup job on a target

        :param target: Backup target with the backup data
        :type  target: Instance of :class:`.BackupTarget`

        :param job: Backup target job to resume
        :type  job: Instance of :class:`.BackupTargetJob`

        :rtype: ``bool``
        """
        raise NotImplementedError("resume_target_job not implemented for this driver")

    def suspend_target_job(self, job):
        """
        Suspend a running backup job on a target

        :param target: Backup target with the backup data
        :type  target: Instance of :class:`.BackupTarget`

        :param job: Backup target job to suspend
        :type  job: Instance of :class:`.BackupTargetJob`

        :rtype: ``bool``
        """
        raise NotImplementedError("suspend_target_job not implemented for this driver")

    def cancel_target_job(self, job):
        """
        Cancel a backup job on a target

        :param target: Backup target with the backup data
        :type  target: Instance of :class:`.BackupTarget`

        :param job: Backup target job to cancel
        :type  job: Instance of :class:`.BackupTargetJob`

        :rtype: ``bool``
        """
        raise NotImplementedError("cancel_target_job not implemented for this driver")
