import json
import os
import select
import subprocess
import sys

from systemimage.config import config
config  # pyflakes


class ApplyUpgradeError(Exception):
    pass


def is_sym_link_broken(path):
    '''
    Returns True if the specified path is a broken symbolic link, else
    False.
    '''
    try:
        os.lstat(path)
        os.stat(path)
    except:
        return True
    return False


class ApplyUpgrade:
    """Hook for system-image-cli"""

    UPGRADER = ["ubuntu-core-upgrade"]
    UPGRADER_ARGS = ["/writable/cache/ubuntu_command"]

    def apply_update(self):
        p = subprocess.Popen(
            self.UPGRADER + self.UPGRADER_ARGS,
            stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        # collect the output while iterating to avoid hitting the 64k
        # pipe size limit (unlikely but...)
        stdout = ""
        while p.poll() is None:
            # send alive ping
            sys.stdout.write(json.dumps({"type": "spinner",
                                         "msg": "Applying update"})+"\n")
            sys.stdout.flush()
            if select.select([p.stdout.fileno()], [], [], 0.1) != ([], [], []):
                stdout += p.stdout.read(1).decode("utf-8", errors="replace")
        # get return code
        ret_code = p.poll()
        # close the pipes
        p.communicate()
        if ret_code != 0:
            raise ApplyUpgradeError(
                "%s exited with %s:\n%s", self.UPGRADER, ret_code, stdout)
        return True

    # entry point for s-i 2.x
    def reboot(self):
        self.apply_update()

    # entry point for s-i 3.0
    def apply(self):
        self.apply_update()
