/* --COPYRIGHT--,EPL
 *  Copyright (c) 2008 Texas Instruments and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 * 
 *  Contributors:
 *      Texas Instruments - initial implementation
 * 
 * --/COPYRIGHT--*/
/*
 *  ======== MetaData.java ========
 */
package xdc.rta;

import java.util.HashMap;
import java.util.Vector;
import java.util.Set;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Document;

import xdc.rov.TargetType;

/*
 *  ======== MetaData ========
 *  Wrapper for the RTA XML file generated for every RTSC application.
 *  
 *  The RTA XML file contains information about the application's target,
 *  loggers, modules, and events. The MetaData class provides APIs for
 *  accessing this information.
 *  
 *  The MetaData object must be initialized using one of the parse APIs.
 */
public class MetaData implements IEventMetaData
{
    /* Target information */
    private int argSize = -1; // Target arg size in bytes
    private int bitsPerChar = -1;
    private int eventSize = -1;
    private String targetName = "";
    private TargetType.Endianess endian;

    /* Modules */
    private HashMap<Integer, String> modIdToName = null;
    private HashMap<String, Integer> modNameToId = null;
    private HashMap<String, DiagConfig> modNameToDiags = null;
    private HashMap<String, String> modNameToLogger = null;

    /* Events */
    private HashMap<Integer, String> evtIdToName = null;
    private HashMap<String, Integer> evtNameToId = null;
    private HashMap<Integer, String> evtIdToMsg = null;

    /* Loggers */
    private String[] loggerNames = null;
    private HashMap<String, Integer> loggerToId = null;
    private Vector<Logger> loggers = null;

    /* Object file reader for looking up Log_print strings */
    private String binaryParserClass = "";
    private IOFReader ofReader = null;

    /* Class names of data and control transports to use for this app. */
    private String dataTransportClassName = "";
    private String controlTransportClassName = "";
    
    /*!
     *  ======== Logger ========
     *  Contains the properties of a target logger instance.
     */
    public class Logger {
        public int id;
        
        /* A name to associate with this logger instance. */
        public String name;

        /* The name of the logger module. */
        public String type;
        
        public Node metaArgs;
        
        /* The list of modules which log to this logger. */
        public Vector<String> modules;
        
        public Logger()
        {
            modules = new Vector<String>();
        }
    }
            
    /*
     *  ======== getBitsPerChar ========
     *  Returns the MAU size for this target in bits.
     */
    public int getBitsPerChar()
    {
        return (this.bitsPerChar);
    }
    
    /*
     *  ======== getControlTransportClass ========
     */
    public String getControlTransportClass()
    {
        return (this.controlTransportClassName);
    }
    
    /*
     *  ======== getDataTransportClass ========
     */
    public String getDataTransportClass()
    {
        return (this.dataTransportClassName);
    }
    
    /*
     *  ======== getEndianess ========
     */
    public TargetType.Endianess getEndianess()
    {
        return (this.endian);
    }   
    
    /*
     *  ======== getEventNames ========
     */
    public String[] getEventNames()
    {
        Set<String> keys = evtNameToId.keySet();
        
        return (keys.toArray(new String [0]));
    }
    
    /*
     *  ======== getLogger ========
     */
    public Logger getLogger(int loggerId)
    {
        return (loggers.get(loggerId));
    }
    
    /*
     *  ======== getLoggerMetaArgs ========
     *  Returns the meta data associated with the specified logger instance.
     */
    public Node getLoggerMetaArgs(int loggerId)
    {
        return (loggers.get(loggerId).metaArgs);
    }

    /*
     *  ======== getLoggerNames ========
     *  Lists all the loggers in the system.
     */
    public String[] getLoggerNames()
    {        
        return (loggerNames);
    }
    
    /*
     *  ======== getLoggersModules =========
     *  Returns the list of modules associated with a given logger instance.
     */
    public String[] getLoggersModules(String loggerName)
    {
        int loggerId = lookupLoggerId(loggerName);
        
        Logger logger = this.loggers.get(loggerId); 
        
        return (logger.modules.toArray(new String[0]));
    }
    
    /*
     *  ======== getModuleDiagConfig ========
     *  Gets the initial diagnostics configuration for the given module.
     */
    public DiagConfig getModuleDiagConfig(String moduleName) {
        return (this.modNameToDiags.get(moduleName));
    }
    
    /* 
     *  ======== getModuleLogger ========
     *  Returns the logger instance associated with the specified module.
     */
    public String getModuleLogger(String moduleName) {
        return (this.modNameToLogger.get(moduleName));
    }
    
    /*
     *  ======== getModuleNames ========
     */
    public String[] getModuleNames()
    {
        Set<String> keys = modNameToId.keySet();
        
        return (keys.toArray(new String [0]));
    }
    
    /*
     *  ======== getOFReader ========
     */
    public IOFReader getOFReader()
    {
        return (ofReader);
    }
    
    /*!
     *  ======== getProperty ========
     *  Helper function to retrieve the specified target property from the RTA
     *  XML file.
     *  
     *  These target properties are single XML elements whose values are the
     *  text content of the element.
     */
    public String getProperty(Document doc, String name) 
    {
        /* Retrieve this properties node */
        Node n = doc.getElementsByTagName(name).item(0);
        
        Node child = n.getFirstChild(); 
        
        /* Make sure the XML element isn't empty. */
        if (child == null) {
            return ("");
        }
        
        /* Return the value of this property */
        return (child.getNodeValue());
    }
    
    public String getProperty(Element elem, String name) 
    {
        /* Retrieve the property node. */
        Node n = elem.getElementsByTagName(name).item(0);
        
        Node child = n.getFirstChild();
        
        /* Make sure the XML element isn't empty. */
        if (child == null) {
            return ("");
        }
        
        /* Return the value of this property */
        return (child.getNodeValue());
    }

    /*
     *  ======== getTargetArgSize ========
     *  Returns the target size of a record argument in bytes (not MAUs).
     */
    public int getTargetArgSize()
    {
        return (this.argSize);
    }
    
    /*
     *  ======== getTargetEventRecSize ========
     *  Returns the record size in bytes (not MAUs).
     */
    public int getTargetEventRecSize()
    {
        return (this.eventSize);
    }
    
    /*
     *  ======== getTargetName ========
     */
    public String getTargetName()
    {
        return (this.targetName);
    }
    
    /*
     *  ======== getXMLFromExec ========
     *  Retrieves the path to a given application's RTA XML file.
     */
    public static String getXMLFromExec(String executable) throws Exception
    {
        return (Recap.locateRecap(executable, ".rta.xml"));
    }
    
    /*
     *  ======== lookupEventId ========
     */
    public int lookupEventId(String eventName)
    {
        Integer res = this.evtNameToId.get(eventName);
        return (res == null ? -1 : res);
    }
    
    /*
     *  ======== lookupEventMessage ========
     *  Returns the format string for the message with the given name.
     */
    public String lookupEventMessage(String eventName)
    {
        return (lookupEventMessage(this.lookupEventId(eventName)));
    }
    
    public String lookupEventMessage(int eventId) {
        return (this.evtIdToMsg.get(eventId));
    }
    
    /*
     *  ======== lookupEventModule ========
     *  The event name contains the module name, e.g., xdc.runtime.Log.L_create
     */
    public String lookupEventModule(String eventName) 
    {
        return (eventName.substring(0, eventName.lastIndexOf(".")));
    }
    
    /*
     *  ======== lookupEventName ========
     */
    public String lookupEventName(int eventId) {
        return (this.evtIdToName.get(eventId));
    }
             
    /*
     *  ======== lookupLoggerId ========
     */
    public int lookupLoggerId(String loggerName)
    {
        Integer res = this.loggerToId.get(loggerName);
        return (res == null ? -1 : res);
    }
    
    /*
     *  ======== lookupModuleId ========
     */
    public int lookupModuleId(String moduleName)
    {
        Integer res = this.modNameToId.get(moduleName);
        return (res == null ? -1 : res);
    }

    /*
     *  ======== lookupModuleName ========
     */
    public String lookupModuleName(int modId) {
        return (this.modIdToName.get(modId));
    }  
    
    /*
     *  ======== parse ========
     *  Initialize the MetaData instance with the given paths to the RTA XML
     *  file and executable.
     */
    public String parse(String xmlFile, String executable)
    {
        /* Modules */
        modNameToId = new HashMap<String, Integer>();
        modIdToName = new HashMap<Integer, String>();
        modNameToDiags = new HashMap<String, DiagConfig>();
    
        /* Events */
        evtNameToId = new HashMap<String, Integer>();
        evtIdToName = new HashMap<Integer, String>();
        evtIdToMsg = new HashMap<Integer, String>();
        
        /* Loggers */
        loggers = new Vector<Logger>();
        modNameToLogger = new HashMap<String, String>();
        loggerToId = new HashMap<String, Integer>();
        
        Document doc = null;
        
        /* Parse the XML file into a Document object. */
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            doc = builder.parse(new File(xmlFile).toURI().toString());
        }
        catch (javax.xml.parsers.ParserConfigurationException e) {
            return ("Can't create XML parser: " + e.toString());
        }
        catch (java.io.IOException e) {
            return ("Can't read RTA XML file " + xmlFile + ": " + e.toString());
        }
        catch (org.xml.sax.SAXException e) {
            return ("Can't parse RTA XML file " + xmlFile +": " + e.toString());
        }
        
        /* Retrieve the target-specific properties */
        String res = parseTargetProps(doc);
        if (res != "") {
            return (res);
        }
        
        /* Retrieve the list of loggers and their properties. */
        parseLoggers(doc);
        
        /* Retrieve the mapping of modules to ids and the module properties. */
        parseModules(doc, xmlFile);
                
        /* Retrieve the event information. */
        res = parseEventMap(doc, xmlFile);
        if (res != "") {
            return (res);
        }

        /* Initialize the object file reader. */
        res = initOfReader(executable);
        if (res != "") {
            return (res);
        }
        
        return ("");
    }
    
    /*
     *   ======== parseFromExec ========
     *   Retrieves the RTA XML file for the given executable and uses it to
     *   initialize the MetaData object.
     */
    public String parseFromExec(String executable) throws Exception
    {
        /* 
         * TODO - Read the parser from the executable using Vers so that
         * you can use it to extract the embedded recap file.
         */
         
        /* Retrieve the path to the XML file from the executable. */
        String xmlFile = getXMLFromExec(executable);
        
        /* Call parse and return the result. */
        String result = parse(xmlFile, executable); 
        
        return (result);
    }    
    
    /*
     *  ======== initOfReader ========
     *  Initialize the object file reader used to retrieve Log_print format
     *  strings.
     *  
     *  The object file reader class name comes from the RTA XML file.
     */
    private String initOfReader(String executable) 
    {
        /* 
         * If we don't have the executable, or no binary parser class was
         * specified, don't fail; just don't initialize ofReader.
         */
        if (executable == null) {
            System.out.println("RTA: Executable not specified, cannot " +
                               "lookup Log_print strings.");
            return ("");
        }
        else if ((this.binaryParserClass == null) ||
                 (this.binaryParserClass == "")) {
            System.out.println("RTA: Binary file parser not specified, " +
                               "cannot lookup Log_print strings.");
            return ("");
        }
        
        try {
            /* Instantiate the object file reader. */
            Class<?> c = Class.forName(this.binaryParserClass);
            ofReader = (IOFReader) c.newInstance();
        
            /* Initialize the object file reader. */
            String err = ofReader.parse(executable);
            if (err != "") {
                return("RTA failed to parse " + executable + ": " + err);
            }
            else {
                /* 
                 * Close the file. Reader will re-open it automatically to
                 * read strings.
                 */
                ofReader.close();
            }
        }
        catch (IOException e) {
            return ("RTA failed to parse object file: " + e);
        }
        catch (ClassNotFoundException e) {
            return ("RTA could not locate the specified binary parser " +
                    "class: " + e);
        }
        catch (IllegalAccessException e) {
            return ("RTA failed to instantiate binary parser class: " + e);
        }
        catch (InstantiationException e) {
            return ("RTA failed to instantiate binary parser class: " + e);
        }
        
        /* 
         * Set the Formatter's OFReader so that it can perform String
         * lookups (%s) when formatting printf strings.
         */
        Formatter.setOFReader(ofReader);
        
        /* Return success. */
        return ("");
    }
    
    /*
     *  ======== parseEventMap ========
     *  Helper function to retrieve all of the event information.
     */
    private String parseEventMap(Document doc, String xmlFile)
    {
        /* Get all of the events. */
        NodeList evtMap = doc.getElementsByTagName("evtMap");
        
        /* For each event... */
        for (int i = 0; i < evtMap.getLength(); i++) {
            Element elem = (Element) evtMap.item(i);
            
            /* Get the event's name in the 'key' attribute */
            String name = elem.getAttribute("key");
            
            /* Get the event's id. */
            int id = Integer.parseInt(getProperty(elem, "id"));
            
            /* Map the event name to id and vice versa. */
            this.evtNameToId.put(name, id);
            this.evtIdToName.put(id, name);
            
            /* Get the event's message. */
            String msg = getProperty(elem, "msg");
            
            /* Map the event id to the event message. */
            try {
                this.evtIdToMsg.put(id, 
                                    java.net.URLDecoder.decode(msg, "UTF-8"));
            }
            catch (java.io.UnsupportedEncodingException e) {
                return ("XMl file " + xmlFile + " contains unsupported " + 
                        "encodings: " + e.toString());
            }
        }
        
        return ("");
    }
    
    /*
     *  ======== parseLoggers ========
     *  Retrieve the list of loggers so that we have them in the same
     *  order as the target.
     */
    private void parseLoggers(Document doc)
    {
        NodeList loggerList = doc.getElementsByTagName("loggers");
        for (int i = 0; i < loggerList.getLength(); i++) {
            Element elem = (Element) loggerList.item(i);
            Logger logger = new Logger();
            
            /* The log's id is its index in the list. */
            logger.id = i;
                        
            /* Preserve compatibility. Older XML files just have logger name. */
            if (elem.getChildNodes().getLength() == 1) {
                logger.name = elem.getTextContent();
                loggers.add(logger);
                this.loggerToId.put(logger.name, i);
                
                continue;
            }
            
            /* Get the logger name. */
            logger.name = getProperty(elem, "name");

            /* Get the logger type. */
            logger.type = getProperty(elem, "type");
            
            /* Get the meta args. */
            logger.metaArgs = elem.getElementsByTagName("metaArgs").item(0);
            
            /* Map id to logger and logger to id */
            loggers.add(logger);
            this.loggerToId.put(logger.name, i);
        }
                
        /* Create a String array of the logger names for getLoggerNames */
        loggerNames = new String[loggers.size()];
        for (int i = 0; i < loggers.size(); i++) {
            loggerNames[i] = loggers.get(i).name;
        }
    }
    
    /*!
     *  ======== parseModules ========
     *  Parse the modMap, which maps module names to their id, logger,
     *  and diags settings.
     */
    private void parseModules(Document doc, String xmlFile) 
    {
        /* Get all of the module nodes. */
        NodeList modMap = doc.getElementsByTagName("modMap");
        
        /* For each module... */
        for (int i = 0; i < modMap.getLength(); i++) {
            Element elem = (Element) modMap.item(i);
            
            /* Get the module's name which is stored in the 'key' attribute. */
            String modName = elem.getAttribute("key");
            
            /* Get the module's id. */
            int id = Integer.parseInt(getProperty(elem, "id"));
            
            /* Map the module's id to name and vice versa. */
            this.modNameToId.put(modName, id);
            this.modIdToName.put(id, modName);
            
            /* Get the module's logger. */
            String loggerName = getProperty(elem, "logger");

            /* 
             * Map the module to its logger, but don't map modules with a
             * null logger. 
             */
            if (!loggerName.equals("null")) {
                /* Map module name to logger */
                this.modNameToLogger.put(modName, loggerName);
    
                /* Map logger to list of modules. */
                int loggerId = lookupLoggerId(loggerName);
                Logger logger = loggers.get(loggerId);
                logger.modules.add(modName);
            }
            
            /* Get the module's initial diags mask. */
            String diagsMask = getProperty(elem, "diagsMask");
            
            /* Create a DiagConfig object from the mask string */
            DiagConfig diags = new DiagConfig(diagsMask);

            /* Map the module to its diags mask. */
            this.modNameToDiags.put(modName, diags);
        }
    }
    
    /*!
     *  ======== parseTargetProps ========
     *  Helper function to retrieve all of the target properties from the
     *  RTA XML file.
     */
    private String parseTargetProps(Document doc) 
    {
        /* Name of the target. */
        this.targetName = getProperty(doc, "targetName");
            
        /* Get the target endianess. */
        String endianStr = getProperty(doc, "endian");
        
        /* Convert the endianess to its enum form. */
        try {
            this.endian = TargetType.strToEndianess(endianStr);       
        }
        catch (Exception e) {
            return (e.toString());
        }
        
        /* Get the target's MAU size. */
        this.bitsPerChar = Integer.parseInt(getProperty(doc, "bitsPerChar"));
        
        /* Get the MAU size of the IArg type, convert it to bytes. */
        this.argSize = Integer.parseInt(getProperty(doc, "argSize"));
        this.argSize = this.argSize * (this.bitsPerChar / 8);
        
        /* Get the MAU size of an event record, convert it to bytes. */
        this.eventSize = Integer.parseInt(getProperty(doc, "eventSize"));
        this.eventSize = this.eventSize * (this.bitsPerChar / 8);            
        
        /* Get the name of the object file reader class. */
        this.binaryParserClass = getProperty(doc, "binaryParser"); 
        
        /* 
         * Get the class names of the data and control transport classes to
         * use on the host in communicating with this target application.
         *
         * We need to preserve backwards compatibility with XML files that
         * don't contain this information. Check for it before trying to
         * retrieve it.
         */
        if (doc.getElementsByTagName("dataTransportClassName").getLength() != 0) {
            this.dataTransportClassName = 
                getProperty(doc, "dataTransportClassName");
            this.controlTransportClassName =
                getProperty(doc, "controlTransportClassName");
        }

        return ("");
    }
}
