from . import Atomic
from . import util
from docker.errors import NotFound
from docker.errors import APIError
import sys

class Delete(Atomic):
    def __init__(self):
        super(Delete, self).__init__()

    def delete_image(self):
        """
        Mark given image(s) for deletion from registry
        :return: 0 if all images marked for deletion, otherwise 2 on any failure
        """

        if not self.args.assumeyes:
            confirm = util.input("Do you wish to delete {}? (y/N) ".format(self.args.delete_targets))
            confirm = confirm.strip().lower()
            if not confirm in ['y', 'yes']:
                util.write_err("User aborted delete operation for {}".format(self.args.delete_targets))
                sys.exit(2)

        if self.args.remote:
            results = self._delete_remote(self.args.delete_targets)
        else:
            results = self._delete_local(self.args.delete_targets, self.args.force)
        return results

    def prune_images(self):
        """
        Remove dangling images from registry
        :return: 0 if all images deleted or no dangling images found
        """
        self.syscontainers.prune_ostree_images()

        results = self.d.images(filters={"dangling":True}, quiet=True)
        if len(results) == 0:
            return 0

        for img in results:
            self.d.remove_image(img, force=True)
            util.write_out("Removed dangling Image {}".format(img))
        return 0

    def _delete_remote(self, targets):
        results = 0
        for target in targets:
            # _convert_to_skopeo requires registry v1 support while delete requires v2 support
            # args, img = self.syscontainers._convert_to_skopeo(target)

            args = []
            if "http:" in target:
                args.append("--insecure")

            for i in ["oci:", "http:", "https:"]:
                img = target.replace(i, "docker:")

            if not img.startswith("docker:"):
                img = "docker://" + img

            try:
                util.skopeo_delete(img, args)
                util.write_out("Image {} marked for deletion".format(img))
            except ValueError as e:
                util.write_err("Failed to mark Image {} for deletion: {}".format(img, e))
                results = 2
        return results

    def _delete_local(self, targets, force=False):
        results = 0
        for target in targets:
            if not self.args.storage:
                if self.is_duplicate_image(target):
                    util.write_err("Failed to delete Image {}: has duplicate naming; please specify "
                                   "--storage to delete from a specific storage.".format(target))
                    results = 2
                else:
                    if self.syscontainers.has_image(target):
                        self.syscontainers.delete_image(target)
                    else:
                        try:
                            self.d.remove_image(target, force=force)
                        except NotFound as e:
                            util.write_err("Failed to delete Image {}: {}".format(target, e))
                            results = 2
                        except APIError as e:
                            util.write_err("Failed operation for delete Image {}: {}".format(target, e))
                            results = 2

            elif self.args.storage.lower() == "ostree":
                if not self.syscontainers.has_image(target):
                    util.write_err("Failed to delete Image {}: does not exist in ostree.".format(target))
                self.syscontainers.delete_image(target)

            elif self.args.storage.lower() == "docker":
                try:
                    self.d.remove_image(target, force=force)
                except NotFound as e:
                    util.write_err("Failed to delete Image {}: {}".format(target, e))
                    results = 2
                except APIError as e:
                    util.write_err("Failed operation for delete Image {}: {}".format(target, e))
                    results = 2

            else:
                util.write_err("{} is not a valid storage".format(self.args.storage))
                results = 2

        return results
