import java.util.*;
import java.io.*;
import java.net.*;

import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;

import java.math.BigInteger;

import user.*;
import config.*;

/********************************************************
 * 
 *******************************************************/

public class User
{
  static  List<KiParConfiguration.SBOIdentifier> SBO_Identifier;
  static  List<KiParConfiguration.GOIdentifier> GO_Identifier;
  static  List<KiParConfiguration.ECNumber> EC_Number;
  static  String Keywords;
  static  int    weight_EC;
  static  int    weight_CPD;
  static  int    weight_SCE;
  static  int    weight_RN;
  static  int    weight_GO;
  static  int    weight_PATH;
  static  int    weight_SBO;
  static  String KiPar_Driver;
  static  String KiPar_URL;
  static  String KiPar_Username;
  static  String KiPar_Password;
  static  String PubChem_Driver;
  static  String PubChem_URL;
  static  String PubChem_Username;
  static  String PubChem_Password;
  static  String UMLS_Year;
  static  String UMLS_Host;
  static  String Literature_Database;
  static  BigInteger Export_Items;
  static  BigInteger Export_Max;
  static  String Start;
  static  String End;

  static  String SBOs = "";
  static  String GOs  = "";
  static  String ECs  = "";

  public static void main(String[] args) throws Exception
  {
    // --- read the user file in the following XML format:

    // ---------------------------------------------------------------------------
    // <KiPar_Configuration>
    // <SBO_Identifier>
    //   <SBO_Identifier>...</SBO_Identifier>
    // </SBO_Identifier>
    // ...
    // <SBO_Identifier>
    //   <SBO_Identifier>...</SBO_Identifier>
    // </SBO_Identifier>
    // <GO_Identifier>
    //   <GO_Identifier>...</GO_Identifier>
    // </GO_Identifier>
    // ...
    // <GO_Identifier>
    //   <GO_Identifier>...</GO_Identifier>
    // </GO_Identifier>
    // <EC_Number>
    //   <EC_Number>...</EC_Number>
    // </EC_Number>
    // ...
    // <EC_Number>
    //   <EC_Number>...</EC_Number>
    // </EC_Number>
    // <Keywords>...</Keywords>
    // <Weights>
    //   <EC>...</EC>
    //   <CPD>...</CPD>
    //   <SCE>...</SCE>
    //   <RN>...</RN>
    //   <GO>...</GO>
    //   <PATH>...</PATH>
    //   <SBO>...</SBO>
    // </Weights>
    // <KiPar>
    //   <Driver>...</Driver>
    //   <URL>...</URL>
    //   <Username>...</Username>
    //   <Password>...</Password>
    //   </KiPar>
    // <PubChem>
    //   <Driver>...</Driver>
    //   <URL>...</URL>
    //   <Username>...</Username>
    //   <Password>...</Password>
    // </PubChem>
    // <UMLS>
    //   <Year>...</Year>
    //   <Host>...</Host>
    //   </UMLS>
    // <Literature_Database>...</Literature_Database>
    // <Export>
    //   <Items>...</Items>
    //   <Max>...</Max>
    // </Export>
    // <Start>...</Start>
    // <End>...</End>
    // </KiPar_Configuration>
    // ---------------------------------------------------------------------------

    // --- prepare for XML unmarshalling
    JAXBContext jc;            // --- JAXBContext object to provide entry point to JAXB API
    Unmarshaller unmarshaller; // --- Unmarshaller object to control the process of unmarshalling

    jc = JAXBContext.newInstance("user");
    unmarshaller = jc.createUnmarshaller();

    user.KiParConfiguration userConfig = (user.KiParConfiguration) unmarshaller.unmarshal(new File("user.xml"));

    SBO_Identifier = userConfig.getSBOIdentifier();

    Iterator<KiParConfiguration.SBOIdentifier> sboItr = SBO_Identifier.iterator();
    while(sboItr.hasNext())
    {
      KiParConfiguration.SBOIdentifier sboEl = sboItr.next();
      String sbo = sboEl.getSBOIdentifier();
      SBOs += sbo + "\n";
    }
    int l = SBOs.length();
    if (l > 0) SBOs = SBOs.substring(0, l-1);

    GO_Identifier = userConfig.getGOIdentifier();
    Iterator<KiParConfiguration.GOIdentifier> goItr = GO_Identifier.iterator();
    while(goItr.hasNext())
    {
      KiParConfiguration.GOIdentifier goEl = goItr.next();
      String go = goEl.getGOIdentifier();
      GOs += go + "\n";
    }
    l = GOs.length();
    if (l > 0) GOs = GOs.substring(0, l-1);

    EC_Number = userConfig.getECNumber();
    Iterator<KiParConfiguration.ECNumber> ecItr = EC_Number.iterator();
    while(ecItr.hasNext())
    {
      KiParConfiguration.ECNumber ecEl = ecItr.next();
      String ec = ecEl.getECNumber();
      ECs += ec + "\n";
    }
    l = ECs.length();
    if (l > 0) ECs = ECs.substring(0, l-1);

    Keywords = userConfig.getKeywords();

    user.KiParConfiguration.Weights weights = userConfig.getWeights();
    weight_EC   = weights.getEC();
    weight_CPD  = weights.getCPD();
    weight_SCE  = weights.getSCE();
    weight_RN   = weights.getRN();
    weight_GO   = weights.getGO();
    weight_PATH = weights.getPATH();
    weight_SBO  = weights.getSBO();

    user.LocalDatabase kipar = userConfig.getKiPar();
    KiPar_Driver   = kipar.getDriver();
    KiPar_URL      = kipar.getURL();
    KiPar_Username = kipar.getUsername();
    KiPar_Password = kipar.getPassword();

    user.LocalDatabase pubchem = userConfig.getPubChem();
    PubChem_Driver   = pubchem.getDriver();
    PubChem_URL      = pubchem.getURL();
    PubChem_Username = pubchem.getUsername();
    PubChem_Password = pubchem.getPassword();

    user.KiParConfiguration.UMLS umls = userConfig.getUMLS();
    UMLS_Year = umls.getYear();
    UMLS_Host = umls.getHost();

    Literature_Database = userConfig.getLiteratureDatabase();

    user.KiParConfiguration.Export export = userConfig.getExport();
    Export_Items = export.getItems();
    Export_Max   = export.getMax();

    Start = userConfig.getStart();
    End   = userConfig.getEnd();

    printUser();

    updateConfig();
  }

  private static void printUser()
  {
    System.out.println("<KiPar_Configuration>");
    System.out.println("<SBO_Identifier>");
    System.out.println(SBOs);
    System.out.println("</SBO_Identifier>");
    System.out.println("<GO_Identifier>");
    System.out.println(GOs);
    System.out.println("</GO_Identifier>");
    System.out.println("<EC_Number>");
    System.out.println(ECs);
    System.out.println("</EC_Number>");
    System.out.println("  <Keywords>" + Keywords + "</Keywords>");
    System.out.println("  <Weights>");
    System.out.println("    <EC>" + weight_EC + "</EC>");
    System.out.println("    <CPD>" + weight_CPD + "</CPD>");
    System.out.println("    <SCE>" + weight_SCE + "</SCE>");
    System.out.println("    <RN>" + weight_RN + "</RN>");
    System.out.println("    <GO>" + weight_GO + "</GO>");
    System.out.println("    <PATH>" + weight_PATH + "</PATH>");
    System.out.println("    <SBO>" + weight_SBO + "</SBO>");
    System.out.println("  </Weights>");
    System.out.println("  <KiPar>");
    System.out.println("    <Driver>" + KiPar_Driver + "</Driver>");
    System.out.println("    <URL>" + KiPar_URL + "</URL>");
    System.out.println("    <Username>" + KiPar_Username + "</Username>");
    System.out.println("    <Password>" + KiPar_Password + "</Password>");
    System.out.println("  </KiPar>");
    System.out.println("  <PubChem>");
    System.out.println("    <Driver>" + PubChem_Driver + "</Driver>");
    System.out.println("    <URL>" + PubChem_URL + "</URL>");
    System.out.println("    <Username>" + PubChem_Username + "</Username>");
    System.out.println("    <Password>" + PubChem_Password + "</Password>");
    System.out.println("  </PubChem>");
    System.out.println("    <Year>" + UMLS_Year + "</Year>");
    System.out.println("    <Host>" + UMLS_Host + "</Host>");
    System.out.println("  <Literature_Database>" + Literature_Database + "</Literature_Database>");
    System.out.println("  <Export>");
    System.out.println("    <Items>" + Export_Items + "</Items>");
    System.out.println("    <Max>" + Export_Max + "</Max>");
    System.out.println("  </Export>");
    System.out.println("  <Start>" + Start + "</Start>");
    System.out.println("  <End>" + End + "</End>");
    System.out.println("</KiPar_Configuration>");
  }

  private static void updateConfig() throws Exception
  {
    String organism                       = "";
    String path                           = "";
    String input_SBO                      = "";
    String input_GO                       = "";
    String input_EC                       = "";
    String input_PubMed                   = "";
    String input_PMC                      = "";
    String output_SBO                     = "";
    String output_GO                      = "";
    String output_PubMed                  = "";
    String output_PMC                     = "";
    String enzyme                         = "";
    String compound                       = "";
    String gene                           = "";
    String enzyme_name                    = "";
    String compound_name                  = "";
    String gene_name                      = "";
    String enzyme2compound                = "";
    String enzyme2gene                    = "";
    String output_UMLS                    = "";
    String output_HTML_PubMed             = "";
    String output_HTML_PMC                = "";
    int    output_HTML_items              = 10;
    int    output_HTML_max                = 300;
    String output_bibtex_PubMed           = "";
    String output_bibtex_PMC              = "";
    String tmp_GO                         = "";
    String tmp_UMLS                       = "";
    String tmp_terms                      = "";
    String tmp_PubMed                     = "";
    String tmp_PMC                        = "";
    String template_UMLS                  = "";
    String umls_language                  = "";
    String options_search                 = "";
    String options_export_HTML            = "";
    String options_export_bibtex          = "";
    String options_export_fullText        = "";
    List<String> options_export_tags_list = new ArrayList<String>();

    // --- prepare for XML unmarshalling
    JAXBContext jc;            // --- JAXBContext object to provide entry point to JAXB API
    Unmarshaller unmarshaller; // --- Unmarshaller object to control the process of unmarshalling

    jc = JAXBContext.newInstance("config");
    unmarshaller = jc.createUnmarshaller();

    config.Data data = (config.Data) unmarshaller.unmarshal(new File("default.xml"));

    organism = data.getOrganism();

    path = data.getPath();

    Data.Files files = data.getFiles();
    Data.Files.Input    input    = files.getInput();
    Data.Files.Output   output   = files.getOutput();
    Data.Files.Tmp      tmp      = files.getTmp();
    Data.Files.Template template = files.getTemplate();

    input_SBO    = input.getSBO();
    input_GO     = input.getGO();
    input_EC     = input.getEC();
    input_PubMed = input.getPubMed();
    input_PMC    = input.getPMC();

    output_SBO    = output.getSBO();
    output_GO     = output.getGO();
    output_UMLS   = output.getUMLS();
    output_PubMed = output.getPubMed();
    output_PMC    = output.getPMC();


    Data.Files.Output.KEGG kegg = output.getKEGG();

    enzyme          = kegg.getEnzyme();
    compound        = kegg.getCompound();
    gene            = kegg.getGene();
    enzyme_name     = kegg.getEnzymeName();
    compound_name   = kegg.getCompoundName();
    gene_name       = kegg.getGeneName();
    enzyme2compound = kegg.getEnzyme2Compound();
    enzyme2gene     = kegg.getEnzyme2Gene();

    Data.Files.Output.HTML html = output.getHTML();
    output_HTML_PubMed = html.getPubMed();
    output_HTML_PMC    = html.getPMC();
    output_HTML_items  = html.getItems();
    output_HTML_max    = html.getMax();

    Data.Files.Output.Bibtex bibtex = output.getBibtex();
    output_bibtex_PubMed = bibtex.getPubMed();
    output_bibtex_PMC    = bibtex.getPMC();

    tmp_GO     = tmp.getGO();
    tmp_UMLS   = tmp.getUMLS();
    tmp_terms  = tmp.getTerms();
    tmp_PubMed = tmp.getPubMed();
    tmp_PMC    = tmp.getPMC();

    template_UMLS = template.getUMLS();

    Data.UMLS umls = data.getUMLS();

    umls_language = umls.getLanguage();


    Data.Options options = data.getOptions();

    options_search   = options.getSearch().value();

    Data.Options.Export export = options.getExport();
    options_export_HTML     = export.getHTML().value();
    options_export_bibtex   = export.getBibtex().value();
    options_export_fullText = export.getFullText().value();

    Data.Options.Export.Tags options_export_tags = export.getTags();
    List tagList = options_export_tags.getTag();

    String newConfig = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + "\n" +
                       "<data>" + "\n" +
                       "   <organism>" + organism + "</organism>" + "\n" +
                       "   <path>" + path + "</path>" + "\n" +
                       "   <files>" + "\n" +
                       "     <input>" + "\n" +
                       "       <SBO>" + input_SBO + "</SBO>" + "\n" +
                       "       <GO>" + input_GO + "</GO>" + "\n" +
                       "       <EC>" + input_EC + "</EC>" + "\n" +
                       "       <PubMed>" + input_PubMed + "</PubMed>" + "\n" +
                       "       <PMC>" + input_PMC + "</PMC>" + "\n" +
                       "     </input>" + "\n" +
                       "     <output>" + "\n" +
                       "       <GO>" + output_GO + "</GO>" + "\n" +
                       "       <SBO>" + output_SBO + "</SBO>" + "\n" +
                       "       <KEGG>" + "\n" +
                       "         <enzyme>" + enzyme + "</enzyme>" + "\n" +
                       "         <compound>" + compound + "</compound>" + "\n" +
                       "         <gene>" + gene + "</gene>" + "\n" +
                       "         <enzyme_name>" + enzyme_name + "</enzyme_name>" + "\n" +
                       "         <compound_name>" + compound_name + "</compound_name>" + "\n" +
                       "         <gene_name>" + gene_name + "</gene_name>" + "\n" +
                       "         <enzyme2compound>" + enzyme2compound + "</enzyme2compound>" + "\n" +
                       "         <enzyme2gene>" + enzyme2gene + "</enzyme2gene>" + "\n" +
                       "       </KEGG>" + "\n" +
                       "       <UMLS>" + output_UMLS + "</UMLS>" + "\n" +
                       "       <PubMed>" + output_PubMed + "</PubMed>" + "\n" +
                       "       <PMC>" + output_PMC + "</PMC>" + "\n" +
                       "       <HTML>" + "\n" +
                       "         <PubMed>" + output_HTML_PubMed + "</PubMed>" + "\n" +
                       "         <PMC>" + output_HTML_PMC + "</PMC>" + "\n" +
                       "         <items>" + Export_Items + "</items>" + "\n" +
                       "         <max>" + Export_Max + "</max>" + "\n" +
                       "       </HTML>" + "\n" +
                       "       <bibtex>" + "\n" +
                       "         <PubMed>" + output_bibtex_PubMed + "</PubMed>" + "\n" +
                       "         <PMC>" + output_bibtex_PMC + "</PMC>" + "\n" +
                       "       </bibtex>" + "\n" +
                       "     </output>" + "\n" +
                       "     <tmp>" + "\n" +
                       "       <GO>" + tmp_GO + "</GO>" + "\n" +
                       "       <UMLS>" + tmp_UMLS + "</UMLS>" + "\n" +
                       "       <terms>" + tmp_terms + "</terms>" + "\n" +
                       "       <PubMed>" + tmp_PubMed + "</PubMed>" + "\n" +
                       "       <PMC>" + tmp_PMC + "</PMC>" + "\n" +
                       "     </tmp>" + "\n" +
                       "     <template>" + "\n" +
                       "       <UMLS>" + template_UMLS + "</UMLS>" + "\n" +
                       "     </template>" + "\n" +
                       "   </files>" + "\n" +
                       "   <database>" + "\n" +
                       "     <driver>" + KiPar_Driver + "</driver>" + "\n" +
                       "     <url>" + KiPar_URL + "</url>" + "\n" +
                       "     <username>" + KiPar_Username + "</username>" + "\n" +
                       "     <password>" + KiPar_Password + "</password>" + "\n" +
                       "   </database>" + "\n" +
                       "   <pubchem>" + "\n" +
                       "     <driver>" + PubChem_Driver + "</driver>" + "\n" +
                       "     <url>" + PubChem_URL + "</url>" + "\n" +
                       "     <username>" + PubChem_Username + "</username>" + "\n" +
                       "     <password>" + PubChem_Password + "</password>" + "\n" +
                       "   </pubchem>" + "\n" +
                       "   <UMLS>" + "\n" +
                       "     <dbYear>" + UMLS_Year + "</dbYear>" + "\n" +
                       "     <language>" + umls_language + "</language>" + "\n" +
                       "     <host>" + UMLS_Host + "</host>" + "\n" +
                       "   </UMLS>" + "\n" +
                       "   <params>" + "\n" +
                       "     <keywords>" + Keywords + "</keywords>" + "\n" +
                       "     <weights>" + "\n" +
                       "       <EC>" + weight_EC + "</EC>" + "\n" +
                       "       <CPD>" + weight_CPD + "</CPD>" + "\n" +
                       "       <SCE>" + weight_SCE + "</SCE>" + "\n" +
                       "       <RN>" + weight_RN + "</RN>" + "\n" +
                       "       <GO>" + weight_GO + "</GO>" + "\n" +
                       "       <PATH>" + weight_PATH + "</PATH>" + "\n" +
                       "       <SBO>" + weight_SBO + "</SBO>" + "\n" +
                       "     </weights>" + "\n" +
                       "   </params>" + "\n" +
                       "   <options>" + "\n" +
                       "     <database>" + Literature_Database + "</database>" + "\n" +
                       "     <search>" + options_search + "</search>" + "\n" +
                       "     <export>" + "\n" +
                       "       <HTML>" + options_export_HTML + "</HTML>" + "\n" +
                       "       <bibtex>" + options_export_bibtex + "</bibtex>" + "\n" +
                       "       <fullText>" + options_export_fullText + "</fullText>" + "\n" +
                       "       <tags>" + "\n";

    int n = tagList.size();
    for (int i = 0; i < n; i++)
    {
      String tag = ((String) tagList.get(i)).trim();
      newConfig += "         <tag>" + tag + "</tag>" + "\n";
    }

    newConfig += "       </tags>" + "\n" +
                 "     </export>" + "\n" +
                 "     <menu>" + "\n" +
                 "       <start>" + Start + "</start>" + "\n" +
                 "       <end>" + End + "</end>" + "\n" +
                 "     </menu>" + "\n" +
                 "   </options>" + "\n" +
                 " </data>" + "\n";

    FileWriter file = null;
    try {file = new FileWriter("config.xml");}
    catch (Exception ex) {System.out.println(ex.toString());}
    file.write(newConfig);
    file.close();

    FileWriter file_SBO = null;
    try {file_SBO = new FileWriter(path + "\\input\\" + input_SBO);}
    catch (Exception ex) {System.out.println(ex.toString());}
    file_SBO.write(SBOs);
    file_SBO.close();

    FileWriter file_GO = null;
    try {file_GO = new FileWriter(path + "\\input\\" + input_GO);}
    catch (Exception ex) {System.out.println(ex.toString());}
    file_GO.write(GOs);
    file_GO.close();

    FileWriter file_EC = null;
    try {file_EC = new FileWriter(path + "\\input\\" + input_EC);}
    catch (Exception ex) {System.out.println(ex.toString());}
    file_EC.write(ECs);
    file_EC.close();
  }
}

