#!/usr/bin/env python
from __future__ import print_function

import os
import sys
import argparse
import subprocess
import json
import globals
import toolconfig
import multi_facility_process_helper_client
import upgradeRelease
import runReleaseScript
import getpass
from globals import UserParamsException

def getHist(name, type):
    ''' Gets the history for this package'''
    ret = {}
    for facility in toolconfig.getListOfFacilities():
        commandsAndArgs = []
        arg = {}
        arg['name'] = name
        arg['type'] = type
        arg['releaseFolder'] = toolconfig.getConfigForFacility(facility)[type]['releaseFolder']
        commandsAndArgs.append(('hist', arg))
        ret[facility] = multi_facility_process_helper_client.executeCommandsOnFacility(facility, commandsAndArgs)
    return ret

def revertRelease(args):
    '''Reverts a IOC/HLA/PyDM/other release to the previous release'''
    packageInfo = toolconfig.determinePackageInfoFromArgs(args)
    if 'name' not in packageInfo:
        raise UserParamsException("Cannot identify package. Please specify the name of the package by either using the --name argument or by running this command in the folder that contains the release for this package.")
    if 'type' not in packageInfo:
        raise UserParamsException("Cannot identify type of package. One way to fix this is to run this command in a folder that contains the release for this package")
    name = packageInfo['name']
    type = packageInfo['type']
    versionsAndReleases = upgradeRelease.determineExistingVersionsAndAvailableReleases(name, type)
    if globals.verbose:
        print("Versions and releases {0}".format(json.dumps(versionsAndReleases)))
    iocFacilityCombos = runReleaseScript.determineIOCFacilityCombos(name, type, args.facility, args.ioc, versionsAndReleases)
    hist = getHist(name, type)
    if globals.verbose:
        print("Hist {0}".format(hist))

    for (facility, ioc, release) in iocFacilityCombos:
        if ioc not in hist[facility][0]:
            print("IOC {0} in facility {1} does not have a history".format(ioc, facility))
            continue
        if len(hist[facility][0][ioc]) <=1:
            print("IOC {0} in facility {1} does not have enough history to revert back.".format(ioc, facility))
            continue

        masterRelease =''
        if 'MASTER' in hist[facility][0]:
            if args.ioc == 'ALL' and len(hist[facility][0]['MASTER']) > 1:
                masterRelease = hist[facility][0]['MASTER'][1]['release']
            else:
                masterRelease = hist[facility][0]['MASTER'][0]['release']

        previousRelease = hist[facility][0][ioc][1]['release']
        print("Reverting {0} in {1} to {2}".format(ioc, facility, previousRelease))

        commandsAndArgs = []
        arg = {}
        arg['name'] = name
        arg['type'] = type
        arg['releaseFolder'] = toolconfig.determineReleaseFolder(facility, name, type)
        arg['linkFolder'] = toolconfig.determineLinkFolder(facility, name, type)
        arg['isMaster'] = ioc == 'MASTER'
#         if ioc == 'MASTER' or previousRelease == masterRelease:
#             arg['isMaster'] = True
#         else:
#             arg['isMaster'] = False
        arg['release'] = previousRelease
        arg['facility'] = facility
        arg['ioc'] = ioc
        arg['user'] = getpass.getuser()
        commandsAndArgs.append(('upgrade', arg))
        results = multi_facility_process_helper_client.executeCommandsOnFacility(facility, commandsAndArgs)
        if not results[0]['status']:
            raise Exception("Reverting" + name +  " of type " +  type +  " isMaster" +  ioc == 'MASTER' +  "ioc/facilty" +  ioc +  facility +  "to" +  previousRelease + " failed")
        if 'preDeployResults' in results[0] and 'stdout' in results[0]['preDeployResults']:
            print(results[0]['preDeployResults']['stdout'])
            if globals.verbose:
                print(results[0]['preDeployResults']['stderr'])
        if 'postDeployResults' in results[0] and 'stdout' in results[0]['postDeployResults']:
            print(results[0]['postDeployResults']['stdout'])
            if globals.verbose:
                print(results[0]['postDeployResults']['stderr'])
        print("Reverted {0} package {1} in facility {2} of type {3} to {4}".format(("ioc " + ioc + " in ") if type in ['SIOC', 'HIOC'] else "", name, facility, type, previousRelease))





def execute(args):
    parser = argparse.ArgumentParser(prog="cram revert", description="Reverts a IOC/HLA/PyDM/other instance to the previous release.")
    parser.add_argument('-v', '--verbose', action='store_true', help='Enable verbose logging')
    parser.add_argument('-n', '--name', help='Specify the application name; we automatically pick this up from the package info if we are running this command in the folder containing the release')
    parser.add_argument('-t', '--type', help='Specifies the type of application from the deployment perspective. Possible values are ' + ", ".join(toolconfig.appTypes.keys()))
    parser.add_argument('-i', '--ioc', help='Reverts to the previous release only on the specified ioc(s). If this is ALL, we revert all IOCs to their individual previous release(s) in the facilities as identified by the facility argument.')
    parser.add_argument('-f', '--facility', help='Reverts to the previous release only on the specified facility(ies). If this is ALL, we revert to the respective previous releases on all facilities. Possible values are - ALL, ' + ", ".join(toolconfig.getListOfFacilities()))
    args = parser.parse_args(args)
    globals.verbose = args.verbose

    try:
        revertRelease(args)
    except UserParamsException as upe:
        if not globals.verbose and not globals.isunittests:
            print(upe)
            sys.exit(-1)
        else:
            raise

if __name__ == "__main__":
    execute(sys.argv[1:])
