import os
import shutil
import json
import toolconfig
import envPathsParser

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


def getTestFolder():
    '''Default test folder is /tmp. Override using the environment variable '''
    testDataFolder = "/tmp"
    if "CRAM_TESTFOLDER" in os.environ:
        testDataFolder = os.environ["CRAM_TESTFOLDER"]
    return testDataFolder

def mk_cd(dir):
    """Make the specified folder and cd into it
    dir is expected to be a child of where we currently are.
    """
    if(not os.path.exists(dir)):
        os.mkdir(dir)
    os.chdir(dir)

def mk(dir):
    """Make the specified folder but stay where you are"""
    os.mkdir(dir)

def mkdirs(paths):
    """Make the specified path but stay where you are"""
    curpath = "."
    for path in paths:
        curpath = os.path.join(curpath, path)
        if not os.path.exists(curpath):
            os.mkdir(curpath)

def cd(dir):
    """Change to the specified folder"""
    os.chdir(dir)

def ln(src, linkname):
    """Create a link in the current folder called linkname pointing to the source"""
    os.symlink(src, linkname)

def touch(fileName, content=''):
    '''Similar to touch, create a file called fileName in the current folder with the specified content'''
    with open(fileName, 'w') as f:
        if content:
            f.write(content)

iocTestFolder = "iocVersionsTest"
def createStdIOCFolders():
    testDataFolder = getTestFolder()
    # Create an iocTop with a couple of versions
    cd(testDataFolder)
    mk_cd(iocTestFolder)
    for facility in toolconfig.getListOfFacilities():
        cd(testDataFolder)
        cd(iocTestFolder)
        mk_cd(facility)
        mk_cd("iocTop")
        mk_cd("testPkg")
        mk("v1")
        mk("v2")
        mk("Development")
        ln("v1", "current")
        # Create a bogus soft link
        ln("bogus_dest", "bogus")
        cd("..")
        mk_cd("otherPkg")
        mk("v1")
        mk("v2")
        ln("v2", "current")
        # Create a software package that is specific to this facility
        cd("..")
        mk_cd(facility + "_specific_package")
        mk("v1")
        mk("v2")
        ln("v2", "current")
        cd("..")
        # Create a package for which another package will be a substring.
        mk_cd("testPkg_suffix")
        mk("v1")
        mk("v2")
        ln("v2", "current")

        # Create some IOCS's; couple of them point to current; one points to the current release but directly (not thru current), one points to something else.
        cd(testDataFolder)
        cd(iocTestFolder)
        cd(facility)
        mk_cd("iocCommon")
        mk_cd("sioc-" + facility + "-001")
        ln("../../iocTop/testPkg/current", "iocSpecificRelease")
        cd("..")
        mk_cd("sioc-" + facility + "-002")
        ln("../../iocTop/testPkg/current", "iocSpecificRelease")
        cd("..")
        mk_cd("sioc-" + facility + "-003")
        ln("../../iocTop/testPkg/v1", "iocSpecificRelease")
        cd("..")
        mk_cd("sioc-" + facility + "-004")
        ln("../../iocTop/testPkg/v2", "iocSpecificRelease")
        cd("..")
        mk_cd("sioc-" + facility + "-005")
        ln("../../iocTop/otherPkg/current", "iocSpecificRelease")
        cd("..")
        mk_cd("sioc-" + facility + "-006")
        ln("../../iocTop/testPkg/v2", "iocSpecificRelease")
        cd("..")
        # Create an IOC with the same name in all facilities.
        mk_cd("sioc-same-name")
        ln("../../iocTop/testPkg/current", "iocSpecificRelease")
        cd("..")

        mk_cd("sioc-" + facility + "-specific01")
        ln("../../iocTop/" + facility + "_specific_package" + "/current", "iocSpecificRelease")
        cd("..")

        mk_cd("sioc- " + facility + "-suffix")
        ln("../../iocTop/testPkg_suffix/current", "iocSpecificRelease")
        cd("..")


        cd(startingDir)



HLATestFolder = "HLATest"
def createStdHLAFolders():
    testDataFolder = getTestFolder()
    # Create an Physics_Top with a couple of versions
    cd(testDataFolder)
    mk_cd(HLATestFolder)
    for facility in toolconfig.getListOfFacilities():
        cd(testDataFolder)
        cd(HLATestFolder)
        mk_cd(facility)
        mk_cd("physicsTop")
        mk_cd("release")
        mk_cd("testPkg")
        mk("v1")
        mk("v2")
        mk("Development")
        cd("..")
        mk_cd("otherPkg")
        mk("v1")
        mk("v2")
        cd("..")
        mk_cd(facility + "_specific_package")
        mk("v1")
        mk("v2")

        # Create some HLA app links
        cd(testDataFolder)
        cd(HLATestFolder)
        cd(facility)
        cd("physicsTop")
        ln("release/testPkg/v1", "testPkg")
        ln("release/otherPkg/v2", "otherPkg")
        ln("release/facility" + "_specific_package" + "/v2", facility + "_specific_package")
        cd("..")
        cd(startingDir)

IOCWorkspaceFolder = "IOC_workspace"
def createNewIOCRelease(name, version):
    '''Simulates the creation of an IOC release outside of iocTop'''
    cd(getTestFolder())
    mk_cd(IOCWorkspaceFolder)
    mk_cd(name)
    mk_cd(version)
    topDir=os.path.abspath(os.path.curdir)
    mk_cd(".cram")
    pkgInfo = {"name" : name, "type" : "SIOC"}
    touch('packageinfo', json.dumps(pkgInfo))
    cd("..")
    mk_cd("iocBoot")
    mk_cd("common")
    touch('envVars.cmd', '''# Environment Variables
epicsEnvSet("EPICS_CA_MAX_ARRAY_BYTES","100000")
''')
    cd('..')

    for ioc in ["sioc-test1-001", "sioc-test1-002", "sioc-test1-003", "sioc-test1-004", "sioc-test1-005", "sioc-test2-001", "sioc-test2-002", "sioc-test2-003", "sioc-test2-004", "sioc-test2-005"]:
        mk(ioc)
        shutil.copy(os.path.join(startingDir, 'sampleEnvPaths.txt'), os.path.join(ioc, "envPaths"))
        envPathsParser.parseAndReplaceEnvPathsFile(os.path.join(ioc, "envPaths"), {'IOC' : ioc, 'TOP' : topDir})
        shutil.copy(os.path.join(startingDir, 'sample_st.cmd'), os.path.join(ioc, "st.cmd"))
    for ioc in ["sioc-test1-006", "sioc-test2-006"]:
        mkdirs(["subFolder", ioc])
        shutil.copy(os.path.join(startingDir, 'sampleEnvPaths.txt'), os.path.join("subFolder", ioc, "envPaths"))
        envPathsParser.parseAndReplaceEnvPathsFile(os.path.join("subFolder", ioc, "envPaths"), {'IOC' : ioc, 'TOP' : topDir})
        shutil.copy(os.path.join(startingDir, 'sample_st.cmd'), os.path.join("subFolder", ioc, "st.cmd"))

    cd("..")
    mk_cd("cpuBoot")
    for cpu in ["cpu-test1-001", "cpu-test1-002"]:
        mk(cpu)
        shutil.copy(os.path.join(startingDir, 'sampleEnvPaths.txt'), os.path.join(cpu, "envPaths"))
        envPathsParser.parseAndReplaceEnvPathsFile(os.path.join(cpu, "envPaths"), {'IOC' : cpu, 'TOP' : topDir})
        shutil.copy(os.path.join(startingDir, 'sample_st.cmd'), os.path.join(cpu, "st.cmd"))

    cd("..")
    touch('README', "Release " + version)
    cd(startingDir)


HLAWorkspaceFolder = "HLA_workspace"
def createNewHLARelease(name, version):
    '''Simulates the creation of an HLA release outside of iocTop'''
    cd(getTestFolder())
    mk_cd(HLAWorkspaceFolder)
    mk_cd(name)
    mk_cd(version)
    mk_cd(".cram")
    pkgInfo = {"name" : name, "type" : "HLA"}
    touch('packageinfo', json.dumps(pkgInfo))
    cd("..")
    touch('README', "Release " + version)
    cd(startingDir)
