import os
import unittest
import shutil
import subprocess
import json
import multi_facility_process_helper
import multi_facility_process_helper_client
import globals
import toolconfig
import testUtils
import runReleaseScript
import upgradeRelease
import pushRelease

startingDir = os.path.realpath(os.curdir)

class TestRun(unittest.TestCase):
    '''Test the run command'''
    testDataFolder = "/tmp"
    
    def setUp(self):
        self.testDataFolder = testUtils.getTestFolder()
        testUtils.createStdIOCFolders()
        testUtils.createStdHLAFolders()
  
         
    def tearDown(self):
        shutil.rmtree(os.path.join(self.testDataFolder, testUtils.iocTestFolder), ignore_errors=True)
        shutil.rmtree(os.path.join(self.testDataFolder, testUtils.HLATestFolder), ignore_errors=True)
        shutil.rmtree(os.path.join(self.testDataFolder, testUtils.IOCWorkspaceFolder), ignore_errors=True)
        shutil.rmtree(os.path.join(self.testDataFolder, testUtils.HLAWorkspaceFolder), ignore_errors=True)

    def test_determineIOCFacilityCombos(self):
        versionsAndReleases = upgradeRelease.determineExistingVersionsAndAvailableReleases('testPkg', 'SIOC')
        iocFacilityCombos = runReleaseScript.determineIOCFacilityCombos('testPkg', 'SIOC', None, 'sioc-test1-001', versionsAndReleases)
        self.assertTrue(('test1', 'sioc-test1-001', 'v1') in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-002', 'v1') not in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-003', 'v1') not in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-004', 'v2') not in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-005', 'v2') not in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-001', 'v1') not in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-002', 'v1') not in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-003', 'v1') not in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-004', 'v2') not in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-005', 'v2') not in iocFacilityCombos)
        iocFacilityCombos = runReleaseScript.determineIOCFacilityCombos('testPkg', 'SIOC', None, 'sioc-test1-001,sioc-test2-002', versionsAndReleases)
        self.assertTrue(('test1', 'sioc-test1-001', 'v1') in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-002', 'v1') not in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-003', 'v1') not in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-004', 'v2') not in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-005', 'v2') not in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-001', 'v1') not in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-002', 'v1') in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-003', 'v1') not in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-004', 'v2') not in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-005', 'v2') not in iocFacilityCombos)
        iocFacilityCombos = runReleaseScript.determineIOCFacilityCombos('testPkg', 'SIOC', 'test1', 'ALL', versionsAndReleases)
        self.assertTrue(('test1', 'sioc-test1-001', 'v1') in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-002', 'v1') in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-003', 'v1') in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-004', 'v2') in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-005', 'v2') not in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-001', 'v1') not in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-002', 'v1') not in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-003', 'v1') not in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-004', 'v2') not in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-005', 'v2') not in iocFacilityCombos)
        iocFacilityCombos = runReleaseScript.determineIOCFacilityCombos('testPkg', 'SIOC', 'test1,test2', 'ALL', versionsAndReleases)
        self.assertTrue(('test1', 'sioc-test1-001', 'v1') in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-002', 'v1') in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-003', 'v1') in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-004', 'v2') in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-005', 'v2') not in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-001', 'v1') in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-002', 'v1') in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-003', 'v1') in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-004', 'v2') in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-005', 'v2') not in iocFacilityCombos)
        iocFacilityCombos = runReleaseScript.determineIOCFacilityCombos('testPkg', 'SIOC', 'ALL', 'ALL', versionsAndReleases)
        self.assertTrue(('test1', 'sioc-test1-001', 'v1') in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-002', 'v1') in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-003', 'v1') in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-004', 'v2') in iocFacilityCombos)
        self.assertTrue(('test1', 'sioc-test1-005', 'v2') not in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-001', 'v1') in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-002', 'v1') in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-003', 'v1') in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-004', 'v2') in iocFacilityCombos)
        self.assertTrue(('test2', 'sioc-test2-005', 'v2') not in iocFacilityCombos)
        self.assertRaises(Exception, runReleaseScript.determineIOCFacilityCombos, 'testPkg', 'SIOC', None, 'ALL', versionsAndReleases)
        self.assertRaises(Exception, runReleaseScript.determineIOCFacilityCombos, 'testPkg', 'SIOC', None, 'unknownIOC', versionsAndReleases)
        self.assertRaises(Exception, runReleaseScript.determineIOCFacilityCombos, 'testPkg', 'SIOC', 'DummyFacility', 'ALL', versionsAndReleases)

    def test_determineHLAFacilityCombos(self):
        versionsAndReleases = upgradeRelease.determineExistingVersionsAndAvailableReleases('testPkg', 'HLA')
        iocFacilityCombos = runReleaseScript.determineIOCFacilityCombos('testPkg', 'HLA', 'test1', None, versionsAndReleases)
        self.assertTrue(('test1', 'MASTER', 'v1') in iocFacilityCombos)
        self.assertTrue(('test2', 'MASTER', 'v1') not in iocFacilityCombos)
        iocFacilityCombos = runReleaseScript.determineIOCFacilityCombos('testPkg', 'HLA', 'test1,test2', None, versionsAndReleases)
        self.assertTrue(('test1', 'MASTER', 'v1') in iocFacilityCombos)
        self.assertTrue(('test2', 'MASTER', 'v1') in iocFacilityCombos)
        iocFacilityCombos = runReleaseScript.determineIOCFacilityCombos('testPkg', 'HLA', 'ALL', None, versionsAndReleases)
        self.assertTrue(('test1', 'MASTER', 'v1') in iocFacilityCombos)
        self.assertTrue(('test2', 'MASTER', 'v1') in iocFacilityCombos)
        self.assertRaises(Exception, runReleaseScript.determineIOCFacilityCombos, 'testPkg', 'HLA', 'DummyFacility', None, versionsAndReleases)

    def test_RunIOCs(self):
        testPushPkgName = "testPkg"
        testPushVersionName = "testPush_V9"
        testUtils.createNewIOCRelease(testPushPkgName, testPushVersionName)
        os.mkdir(os.path.join(self.testDataFolder, testUtils.IOCWorkspaceFolder, testPushPkgName, testPushVersionName, "bin"))
        shutil.copy('prePostDeployTemplate.py', os.path.join(self.testDataFolder, testUtils.IOCWorkspaceFolder, testPushPkgName, testPushVersionName, "bin", "runTest"))
        os.chmod(os.path.join(self.testDataFolder, testUtils.IOCWorkspaceFolder, testPushPkgName, testPushVersionName, "bin", "runTest"), 0754)
        testUtils.cd(os.path.join(self.testDataFolder, testUtils.IOCWorkspaceFolder, testPushPkgName, testPushVersionName))
        pushargs = []
        if globals.verbose:
            pushargs.append('-v')
        pushRelease.execute(pushargs)
 
        upgradeargs = []
        if globals.verbose:
            upgradeargs.append('-v')
        upgradeargs.extend(['--ioc', 'ALL', '--facility', 'ALL', 'testPush_V9'])
        upgradeRelease.execute(upgradeargs)
        testUtils.cd(startingDir)
        
        runargs = []
        if globals.verbose:
            runargs.append('-v')
        runargs.extend(['--name', 'testPkg', '--type', 'SIOC', '--ioc', 'sioc-test1-001', '--facility', 'ALL', 'bin/runTest'])
        runReleaseScript.execute(runargs)
        
        with open(os.path.join(self.testDataFolder, testUtils.iocTestFolder, 'test1', 'iocTop', testPushPkgName, testPushVersionName, 'bin', 'runTest_output.json'), 'r') as f:
            envs = json.load(f)
            for envvar in ['CRAM_SCRIPT', 'CRAM_PACKAGENAME', 'CRAM_PACKAGETYPE', 'CRAM_RELEASEFOLDER', 'CRAM_RELEASE', 'CRAM_LINKFOLDER', 'CRAM_ISMASTER', 'CRAM_FACILITY', 'CRAM_IOC']:
                self.assertTrue(envvar in envs)
