import json
import sys
import shutil
from os import path, remove
import logging
from subprocess import Popen
sys.path.append ('/usr/lib/applmgmt/base/py')
from vmware.vherd.base.config_manager import ConfigManager
from vmware.vherd.base.atomic_write import atomic_write

logger = logging.getLogger(__name__)
WORK_UPDATES="/storage/core/software-update/updates"
STAGE_DIR="/storage/core/software-update/stage"

def _parseBuildInfo():
    buildinfoFile = '/etc/vmware/.buildInfo'
    buildInfoDict = {}
    try:
        with open(buildinfoFile, 'r') as f:
            for line in f.readlines():
                splitLine = line.strip('\n').split(':')
                buildInfoDict[splitLine[0]] = splitLine[1]
    except Exception as e:
        logger.debug("Exception while reading build File %s"%e)
    return buildInfoDict['CLOUDVM_VERSION']

def toJSON(vapiObject):
    '''
    Simple JSON serializer
    '''
    return json.dumps(vapiObject,
                      default=lambda o: {
                          k: v for k, v in o.__dict__.items()
                          if not str(k).startswith('_')},
                      sort_keys=True,
                      indent=4)


def readJsonFile(filename):
    try:
        with open(filename) as f:
            obj = json.load(f)
    except Exception as e:
        logger.debug("Can't read JSON file %s %s", filename, e)
        return
    return obj

def removeDir(directory):
    try:
        shutil.rmtree(directory)
    except IOError as e:
        logger.debug("Can't remove directory %s: %s", directory, e)
    except Exception as e:
        logger.error("Can't remove directory %s: %s", directory, e)

def fix_default_url():
    updateConfJson = ConfigManager("/etc/applmgmt/appliance/update.conf")
    url = updateConfJson['defaultURL']
    if '6.7.0.10000' and '[' in url:
        url_split = url.rsplit("/", 4)[0]
        version_split = url.rsplit("/", 3)[2]
        new_url = "%s/%s/\']" % (url_split, version_split)
        updateConfJson['defaultURL'] = new_url.strip('[]\'')
        with open("/etc/applmgmt/appliance/update.conf",
            'w') as f:
            f.write(toJSON(updateConfJson))
        updateConfJson.commit()

def update_state_before_reboot():
    try:
        STATE_FILE="/etc/applmgmt/appliance/software_update_state.conf"
        state_info  = readJsonFile(STATE_FILE)

        if state_info:

            state_info["state"] = "UP_TO_DATE"

            with atomic_write(STATE_FILE) as f:
                f.write(toJSON(state_info))

            if 'operation_id' in state_info:
                 try:
                     stage_install_file =  state_info["operation_id"]
                     operation = readJsonFile(stage_install_file)
                     if operation["status"] != "RUNNING" :
                         logger.error("Installation is not in running state. Current state : %s",operation["status"])
                         return

                     operation["status"] = "SUCCEEDED"

                     stage_install_progress = operation["progress"]["message"]
                     if (stage_install_progress["default_message"] == "Converting data" and
                         stage_install_progress["id"] == "com.vmware.appliance.patch_in_progress"):

                         operation["progress"]["completed"] = operation["progress"]["total"]
                         operation["progress"]["message"]["default_message"] = "Installation complete.Reload the browser window to continue."
                         operation["progress"]["message"]["id"] = "com.vmware.appliance.install_success"

                         with atomic_write(stage_install_file) as f:
                             f.write(toJSON(operation))

                 except IOError as ex:
                    logger.error("Failed to read % file %s", state_info["operation_id"])

    except Exception as ex:
        logger.error("Exception occurred during update status before reboot machine : %r", ex)

def fix_service_reboot():

    update_state_before_reboot()
    stagePathFile = path.join(STAGE_DIR, 'stageDir.json')
    try:
        stageDir = readJsonFile(stagePathFile)['StageDir']
    except Exception:
        stageDir=""
    # delete the stage directories
    removeDir(STAGE_DIR)
    removeDir(stageDir)
    removeDir(WORK_UPDATES)

version =  _parseBuildInfo()
if version == '6.7.0.10000':
    try:
        fix_default_url()
    except Exception as e:
        logger.debug("Unable to Update the contents of update.conf")

BuildNumber = int(version.split('.')[3])
if BuildNumber < 20000:
    try:
        fix_service_reboot()
    except Exception as e:
        logger.debug('Error during post install cleanup')

