#!/usr/bin/env python

import sys
import getopt
import os

Header="""
! DO NOT EDIT THIS FILE!!!  
!  
! This file is automatically generated by write_network.py at 
! compile-time.  
!  
! To modify the species carried by the network, edit the appropriate inputs 
! file.

"""


#=============================================================================
# the species class holds the properties of a single species
#=============================================================================
class Species(object):

    def __init__(self):
        self.name = ""
        self.shortName = ""
        self.A = -1
        self.Z = -1


#=============================================================================
# get_next_line returns the next, non-blank line, with comments stripped
#=============================================================================
def get_next_line(fin):

    line = fin.readline()

    pos = str.find(line, "#")

    while (pos == 0 or str.strip(line) == "") and line:

        line = fin.readline()
        pos = str.find(line, "#")

    line = line[:pos]

    return line



#=============================================================================
# get_species_index looks through the list and returns the index corresponding to
# the species specified by name
#=============================================================================
def get_species_index(species, name):

    index = -1

    for n in range(len(species)):
        if species[n].name == name:
            index = n
            break

    return index


#=============================================================================
# parse_net_file read all the species listed in a given network inputs file
# and adds the valid species to the species list
#=============================================================================
def parse_net_file(species, net_file):

    err = 0

    try: f = open(net_file, "r")
    except IOError:

        print("write_network.py: ERROR: file "+str(net_file)+" does not exist")
        sys.exit(2)
        
    print("write_network.py: working on network file "+str(net_file)+"...")

    line = get_next_line(f)

    while line and not err:

        fields = line.split()

        if not (len(fields) == 4):
            print(line)
            print("write_network.py: ERROR: missing one or more fields in species definition.")
            err = 1
            continue

        currentSpecies = Species()
            
        currentSpecies.name      = fields[0]
        currentSpecies.shortName = fields[1]
        currentSpecies.A         = fields[2]
        currentSpecies.Z         = fields[3]


        # check to see if this species is defined in the current list
        index = get_species_index(species, currentSpecies.name)

        if index >= 0:
            print("write_network.py: ERROR: species %s already defined." % 
                  (currentSpecies.name))
            err = 1                


            
        species.append(currentSpecies)

        line = get_next_line(f)

    return err


#=============================================================================
# abort exits when there is an error.  A dummy stub file is written out, which
# will cause a compilation failure
#=============================================================================
def abort(outfile):

    fout = open(outfile, "w")
    fout.write("There was an error parsing the network files")
    fout.close()
    sys.exit(1)

    

#=============================================================================
# write_network will read through the list of species and output the 
# new out_file
#=============================================================================
def write_network(network_template, net_file, out_file):

    species = []

    print(" ")
    print("write_network.py: creating %s" % (out_file))


    #-------------------------------------------------------------------------
    # read the species defined in the net_file
    #-------------------------------------------------------------------------
    err = parse_net_file(species, net_file)
        
    if err:
        abort(out_file)


    #-------------------------------------------------------------------------
    # open up the template
    #-------------------------------------------------------------------------
    try: ftemplate = open(network_template, "r")
    except IOError:
        print("write_network.py: ERROR: file "+str(network_template)+" does not exist")
        sys.exit(2)
    else:
        ftemplate.close()

    ftemplate = open(network_template, "r")

    template_lines = []
    line = ftemplate.readline()
    while line:
        template_lines.append(line)
        line = ftemplate.readline()


    #-------------------------------------------------------------------------
    # output the template, inserting the species info in between the @@...@@
    #-------------------------------------------------------------------------
    fout = open(out_file, "w")

    fout.write(Header)

    for line in template_lines:

        index = line.find("@@")

        if index >= 0:
            index2 = line.rfind("@@")

            keyword = line[index+len("@@"):index2]
            indent = index*" "

            if keyword == "NSPEC":

                fout.write(line.replace("@@NSPEC@@", str(len(species))))

            elif keyword == "SPEC_NAMES":

                for n in range(len(species)):
                    fout.write("%sspec_names(%d) = \"%s\"\n" % 
                               (indent, n+1, species[n].name))

            elif keyword == "SHORT_SPEC_NAMES":

                for n in range(len(species)):

                    fout.write("%sshort_spec_names(%d) = \"%s\"\n" % 
                               (indent, n+1, species[n].shortName))

            elif keyword == "AION":

                for n in range(len(species)):

                    fout.write("%saion(%d) = %s\n" % 
                               (indent, n+1, species[n].A))

            elif keyword == "ZION":

                for n in range(len(species)):

                    fout.write("%szion(%d) = %s\n" % 
                               (indent, n+1, species[n].Z))

            elif keyword == "NAME":
                fout.write(line.replace("@@NAME@@", "\"general-"+os.path.basename(net_file)+"\""))
                   
        else:
            fout.write(line)

    print(" ")
    fout.close()


if __name__ == "__main__":

    try: opts, next = getopt.getopt(sys.argv[1:], "t:o:s:")

    except getopt.GetoptError:
        print("write_network.py: invalid calling sequence")
        sys.exit(2)

    network_template = ""
    out_file = ""
    net_file = ""

    for o, a in opts:

        if o == "-t":
            network_template = a

        if o == "-o":
            out_file = a

        if o == "-s":
            net_file = a


    if network_template == "" or out_file == "":
        print("write_probin.py: ERROR: invalid calling sequence")
        sys.exit(2)

    write_network(network_template, net_file, out_file)
