#!/usr/bin/env python
"""This provides a cpuEnv.sh parser and a utility to parse and replace cpuEnv.sh values with a provided dict"""

import os
import sys
from plex import *
import random
import StringIO

# Here's where we define the lexicon for the parser.
# This is parsing a bunch of bash export commands.

letter = Range("AZaz")
digit = Range("09")
hspace = Any(" \t")
nline = Any("\n")
spchars = Any(".-_:{}+/*$<>")
comma = Str(",")
eqsign = Str("=")
quote = Str('"')
name = Rep1(letter | digit | spchars)
nameinquotes = quote + name + quote
space = Any(" \t\n")
openParan = Str("(")
closeParan = Str(")")
comment = Bol + Str("#") + Rep(AnyBut("\n")) + Str("\n")

fileLexicon = Lexicon([
    (comment,  'comment'),
    (space, IGNORE),
    (Str("export"), Begin("Name")),
    State('Name', [
                    (name, 'name'),
                    (quote, IGNORE),
                    (space, IGNORE),
                    (eqsign, Begin("Value"))
                    ]),
    State('Value', [
                    (name, 'value'),
                    (quote, IGNORE),
                    (hspace, IGNORE),
                    (nline, Begin(''))
                    ]),
    (space, IGNORE)
])

def parseAndReplaceEnvPathsFile(envPathsPath, replaceMap):
    '''Parse the envPaths file into a list of tuples that represents the name/value.
    Replace the value of any name that is present in replaceMap with the value from the map.
    Finally update the specified file with the new set of values
    '''
    tempFilePath = os.path.join(os.path.dirname(envPathsPath), "_tmp_multifacility" + str(int(random.random()*1000000)))
    while os.path.exists(tempFilePath):
        stderr.write("Generating a new name for the temporary file\n")
        tempFilePath = os.path.join(os.path.dirname(envPathsPath), "_tmp_multifacility" + str(int(random.random()*1000000)))

    NVPairs = {}
    with open(tempFilePath, 'w') as out:
        with open(envPathsPath, 'r') as f:
            scanner = Scanner(fileLexicon, f, envPathsPath)
            currentName = None
            while 1:
                token = scanner.read()
                if token[0] is None:
                    break
                elif token[0] == "comment":
                     out.write(token[1])
                elif token[0] == 'name':
                    currentName = token[1]
                elif token[0] == 'value':
                    if not currentName:
                        sys.stderr.write("Obtained Value without a name" + token[1])
                        continue
                    if currentName in replaceMap:
                        NVPairs[currentName] = replaceMap[currentName]
                        out.write('export ' + currentName + '=' + replaceMap[currentName] + "\n")
                    else:
                        NVPairs[currentName] = token[1]
                        out.write('export ' + currentName + '=' + token[1] + "\n")
                    currentName = None
                else:
                    sys.stderr.write("Unknown token" + token)
        os.rename(tempFilePath, envPathsPath)
        return NVPairs

# if __name__ == "__main__":
#     parseAndReplaceEnvPathsFile(sys.argv[1], {'TOP': 'ABC123'})
