/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



import java.io.File;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Enumeration;


/**
 * Simple implementation of a inifile manager
 */
class GlobalLogWriter
{
    public static void println(String _s)
    {
        System.out.println(_s);
    }
}

/**
   Helper class to give a simple API to read/write windows like ini files
*/

/* public */ // is only need, if we need this class outside package convwatch
public class IniFile implements Enumeration
{

    /**
     * internal representation of the ini file content.
     * Problem, if ini file changed why other write something difference, we don't realise this.
     */
    private String m_sFilename;
    // private File m_aFile;
    private ArrayList<String> m_aList;
    boolean m_bListContainUnsavedChanges = false;
    private int m_aEnumerationPos = 0;

    /**
       open a ini file by it's name
       @param _sFilename string a filename, if the file doesn't exist, a new empty ini file will create.
       write back to disk only if there are really changes.
    */
    public IniFile(String _sFilename)
        {
            m_sFilename = _sFilename;
            // m_aFile = new File(_sFilename);
            m_aList = loadLines();
            m_aEnumerationPos = findNextSection(0);
        }

    /**
       open a ini file by it's name
       @param _aFile a java.io.File object, if the file doesn't exist, a new empty ini file will create.
       write back to disk only if there are really changes.
    */
    public IniFile(File _aFile)
    {
        m_sFilename = _aFile.getAbsolutePath();
        m_aList = loadLines();
        m_aEnumerationPos = findNextSection(0);
    }

    public void insertFirstComment(String[] _aList)
        {
            if (m_aList.size() == 0)
            {
                // can only insert if there is nothing else already in the ini file
                for (int i = 0; i < _aList.length; i++)
                {
                    m_aList.add(_aList[i]);
                }
            }
        }

    private ArrayList<String> loadLines()
        {
            ArrayList<String> aLines = new ArrayList<String>();
            File aFile = new File(m_sFilename);
            if (!aFile.exists())
            {
                // GlobalLogWriter.println("couldn't find file '" + m_sFilename + "', will be created.");
                // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
                // m_bListContainUnsavedChanges = false;
                return aLines;
            }
            RandomAccessFile aReader = null;
            // BufferedReader aReader;
            try
            {
                aReader = new RandomAccessFile(aFile, "r");
                String aLine = "";
                while (aLine != null)
                {
                    aLine = aReader.readLine();
                    if (aLine != null && aLine.length() > 0)
                    {
                        aLines.add(aLine);
                    }
                }
            }
            catch (java.io.FileNotFoundException fne)
            {
                GlobalLogWriter.println("couldn't open file " + m_sFilename);
                GlobalLogWriter.println("Message: " + fne.getMessage());
                // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
            }
            catch (java.io.IOException ie)
            {
                GlobalLogWriter.println("Exception occurs while reading from file " + m_sFilename);
                GlobalLogWriter.println("Message: " + ie.getMessage());
                // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
            }
            try
            {
                aReader.close();
            }
            catch (java.io.IOException ie)
            {
                GlobalLogWriter.println("Couldn't close file " + m_sFilename);
                GlobalLogWriter.println("Message: " + ie.getMessage());
                // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
            }
            return aLines;
        }

    /**
     * @return true, if the ini file contain some readable data
     */
    public boolean is()
        {
            return m_aList.size() > 1 ? true : false;
        }

    /**
     * Check if a given Section and Key exists in the ini file
     * @param _sSectionName
     * @param _sKey
     * @return true if the given Section, Key exists, now you can get the value
     */
    public boolean hasValue(String _sSectionName, String _sKey)
        {
            int n = findKey(_sSectionName, _sKey);
            if (n > 0)
            {
                return true;
            }
            return false;
        }
    // -----------------------------------------------------------------------------

    private boolean isRemark(String _sLine)
        {
            if (((_sLine.length() < 2)) ||
                (_sLine.startsWith("#")) ||
                (_sLine.startsWith(";")))
            {
                return true;
            }
            return false;
        }

    private String getItem(int i)
        {
            return m_aList.get(i);
        }

    private String buildSectionName(String _sSectionName)
        {
            String sFindSection = "[" + _sSectionName + "]";
            return sFindSection;
        }

    private String sectionToString(String _sSectionName)
        {
            String sKeyName = _sSectionName;
            if (sKeyName.startsWith("[") &&
                sKeyName.endsWith("]"))
            {
                sKeyName = sKeyName.substring(1, sKeyName.length() - 1);
            }
            return sKeyName;
        }

    private String toLowerIfNeed(String _sName)
        {
            return _sName.toLowerCase();
        }

    // return the number where this section starts
    private int findSection(String _sSection)
        {
            String sFindSection = toLowerIfNeed(buildSectionName(_sSection));
            // ----------- find _sSection ---------------
            int i;
            for (i = 0; i < m_aList.size(); i++)
            {
                String sLine = toLowerIfNeed(getItem(i).trim());
                if (isRemark(sLine))
                {
                    continue;
                }
                if (sFindSection.equals("[]"))
                {
                    // special case, empty Section.
                    return i - 1;
                }
                if (sLine.startsWith(sFindSection))
                {
                    return i;
                }
            }
            return -1;
        }

    /**
     * Checks if a given section exists in the ini file
     * @param _sSection
     * @return true if the given _sSection was found
     */
    public boolean hasSection(String _sSection)
        {
            int i = findSection(_sSection);
            if (i == -1)
            {
                return false;
            }
            return true;
        }

    // return the line number, where the key is found.
    private int findKey(String _sSection, String _sKey)
        {
            int i = findSection(_sSection);
            if (i == -1)
            {
                // Section not found, therefore the value can't exist
                return -1;
            }
            return findKeyFromKnownSection(i, _sKey);
        }

    // i must be the index in the list, where the well known section starts
    private int findKeyFromKnownSection(int _nSectionIndex, String _sKey)
        {
            _sKey = toLowerIfNeed(_sKey);
            for (int j = _nSectionIndex + 1; j < m_aList.size(); j++)
            {
                String sLine = getItem(j).trim();

                if (isRemark(sLine))
                {
                    continue;
                }
                if (sLine.startsWith("[") /* && sLine.endsWith("]") */)
                {
                    // TODO: due to the fact we would like to insert an empty line before new sections
                    // TODO: we should check if we are in an empty line and if, go back one line.

                    // found end.
                    break;
                }

                int nEqual = sLine.indexOf("=");
                if (nEqual >= 0)
                {
                    String sKey = toLowerIfNeed(sLine.substring(0, nEqual).trim());
                    if (sKey.equals(_sKey))
                    {
                        return j;
                    }
                }
            }
            return -1;
        }

    // i must be the index in the list, where the well known section starts
    private int findLastKnownKeyIndex(int _nSectionIndex, String _sKey)
        {
            _sKey = toLowerIfNeed(_sKey);
            int i = _nSectionIndex + 1;
            for (int j = i; j < m_aList.size(); j++)
            {
                String sLine = getItem(j).trim();

                if (isRemark(sLine))
                {
                    continue;
                }

                if (sLine.startsWith("[") /* && sLine.endsWith("]") */)
                {
                    // found end.
                    return j;
                }

                int nEqual = sLine.indexOf("=");
                if (nEqual >= 0)
                {
                    String sKey = toLowerIfNeed(sLine.substring(0, nEqual).trim());
                    if (sKey.equals(_sKey))
                    {
                        return j;
                    }
                }
            }
            return i;
        }

    private String getValue(int _nIndex)
        {
            String sLine = getItem(_nIndex).trim();
            if (isRemark(sLine))
            {
                return "";
            }
            int nEqual = sLine.indexOf("=");
            if (nEqual >= 0)
            {
                String sKey = sLine.substring(0, nEqual).trim();
                String sValue = sLine.substring(nEqual + 1).trim();
                return sValue;
            }
            return "";
        }

    /**
       @param _sSection string
       @param _sKey string
       @return the value found in the inifile which is given by the section and key parameter
    */
    // private int m_nCurrentPosition;
    // private String m_sOldKey;
    public String getValue(String _sSection, String _sKey)
        {
            String sValue = "";
            int m_nCurrentPosition = findKey(_sSection, _sKey);
            if (m_nCurrentPosition == -1)
            {
                // Section not found, therefore the value can't exist
                return "";
            }

            // m_sOldKey = _sKey;
            sValue = getValue(m_nCurrentPosition);

            return sValue;
        }

//    private String getNextValue()
//    {
//        if (m_nCurrentPosition >= 0)
//        {
//            ++m_nCurrentPosition;
//            String sValue = getValue(m_nCurrentPosition);
//            return sValue;
//        }
//        return "";
//    }
    /**
     * Returns the value at Section, Key converted to an integer
     * Check with hasValue(Section, Key) to check before you get into trouble.
     * @param _sSection
     * @param _sKey
     * @param _nDefault if there is a problem, key not found... this value will return
     * @return the value as integer if possible to convert, if not return default value.
     */
    public int getIntValue(String _sSection, String _sKey, int _nDefault)
        {
            String sValue = getValue(_sSection, _sKey);
            int nValue = _nDefault;
            if (sValue.length() > 0)
            {
                try
                {
                    nValue = Integer.valueOf(sValue).intValue();
                }
                catch (java.lang.NumberFormatException e)
                {
                    GlobalLogWriter.println("IniFile.getIntValue(): Caught a number format exception, return the default value.");
                }
            }
            return nValue;
        }

/**
 * close a open inifile.
 * If there are changes, all changes will store back to disk.
 */
    public void close()
        {
            store();
        }

    /**
       write back the ini file to the disk, only if there exist changes
       * @deprecated use close() instead!
       */

    // TODO: make private
    private void store()
        {
            if (m_bListContainUnsavedChanges == false)
            {
                // nothing has changed, so no need to store
                return;
            }

            File aFile = new File(m_sFilename);
            if (aFile.exists())
            {
                // System.out.println("couldn't find file " + m_sFilename);
                // TODO: little bit unsafe here, first rename, after write is complete, delete the old.
                aFile.delete();
                if (aFile.exists())
                {
                    GlobalLogWriter.println("Couldn't delete the file " + m_sFilename);
                    return;
                    // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, "Couldn't delete the file " + m_sFilename);
                }
            }
            // if (! aFile.canWrite())
            // {
            //    System.out.println("Couldn't write to file " + m_sFilename);
            //    DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, "");
            // }
            try
            {
                RandomAccessFile aWriter = new RandomAccessFile(aFile, "rw");
                for (int i = 0; i < m_aList.size(); i++)
                {
                    String sLine = getItem(i);
                    if (sLine.startsWith("["))
                    {
                        // write an extra empty line before next section.
                        aWriter.writeByte((int) '\n');
                    }
                    aWriter.writeBytes(sLine);
                    aWriter.writeByte((int) '\n');
                }
                aWriter.close();
            }
            catch (java.io.FileNotFoundException fne)
            {
                GlobalLogWriter.println("couldn't open file for writing " + m_sFilename);
                GlobalLogWriter.println("Message: " + fne.getMessage());
                // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
            }
            catch (java.io.IOException ie)
            {
                GlobalLogWriter.println("Exception occurs while writing to file " + m_sFilename);
                GlobalLogWriter.println("Message: " + ie.getMessage());
                // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
            }
        }

    public void insertValue(String _sSection, String _sKey, int _nValue)
        {
            insertValue(_sSection, _sKey, String.valueOf(_nValue));
        }

    public void insertValue(String _sSection, String _sKey, long _nValue)
        {
            insertValue(_sSection, _sKey, String.valueOf(_nValue));
        }

    /**
       insert a value
       there are 3 cases
       1. section doesn't exist, goto end and insert a new section, insert a new key value pair
       2. section exist but key not, search section, search key, if key is -1 get last known key position and insert new key value pair there
       3. section exist and key exist, remove the old key and insert the key value pair at the same position
     * @param _sSection
     * @param _sKey
     * @param _sValue
     */
    public void insertValue(String _sSection, String _sKey, String _sValue)
        {
            int i = findSection(_sSection);
            if (i == -1)
            {
                // case 1: section doesn't exist
                String sFindSection = buildSectionName(_sSection);

                // TODO: before create a new Section, insert a empty line
                m_aList.add(sFindSection);
                if (_sKey.length() > 0)
                {
                    String sKeyValuePair = _sKey + "=" + _sValue;
                    m_aList.add(sKeyValuePair);
                }
                m_bListContainUnsavedChanges = true;
                return;
            }
            int j = findKeyFromKnownSection(i, _sKey);
            if (j == -1)
            {
                // case 2: section exist, but not the key
                j = findLastKnownKeyIndex(i, _sKey);
                if (_sKey.length() > 0)
                {
                    String sKeyValuePair = _sKey + "=" + _sValue;
                    m_aList.add(j, sKeyValuePair);
                    m_bListContainUnsavedChanges = true;
                }
                return;
            }
            else
            {
                // case 3: section exist, and also the key
                String sKeyValuePair = _sKey + "=" + _sValue;
                m_aList.set(j, sKeyValuePair);
                m_bListContainUnsavedChanges = true;
            }
        }
    // -----------------------------------------------------------------------------
    // String replaceEvaluatedValue(String _sSection, String _sValue)
    //     {
    //         String sValue = _sValue;
    //         int nIndex = 0;
    //         while (( nIndex = sValue.indexOf("$(", nIndex)) >= 0)
    //         {
    //             int nNextIndex = sValue.indexOf(")", nIndex);
    //             if (nNextIndex >= 0)
    //             {
    //                 String sKey = sValue.substring(nIndex + 2, nNextIndex);
    //                 String sNewValue = getValue(_sSection, sKey);
    //                 if (sNewValue != null && sNewValue.length() > 0)
    //                 {
    //                     String sRegexpKey = "\\$\\(" + sKey + "\\)";
    //                     sValue = sValue.replaceAll(sRegexpKey, sNewValue);
    //                 }
    //                 nIndex = nNextIndex;
    //             }
    //             else
    //             {
    //                 nIndex += 2;
    //             }
    //         }
    //         return sValue;
    //     }
    // -----------------------------------------------------------------------------

    // public String getLocalEvaluatedValue(String _sSection, String _sKey)
    //     {
    //         String sValue = getValue(_sSection, _sKey);
    //         sValue = replaceEvaluatedValue(_sSection, sValue);
    //         return sValue;
    //     }

    // -----------------------------------------------------------------------------

    // this is a special behaviour.
    // public String getGlobalLocalEvaluatedValue(String _sSection, String _sKey)
    //     {
    //         String sGlobalValue = getKey("global", _sKey);
    //         String sLocalValue = getKey(_sSection, _sKey);
    //         if (sLocalValue.length() == 0)
    //         {
    //             sGlobalValue = replaceEvaluatedKey(_sSection, sGlobalValue);
    //             sGlobalValue = replaceEvaluatedKey("global", sGlobalValue);
    //             return sGlobalValue;
    //         }
    //         sLocalValue = replaceEvaluatedKey(_sSection, sLocalValue);
    //         sLocalValue = replaceEvaluatedKey("global", sLocalValue);
    //     
    //         return sLocalValue;
    //     }
    public void removeSection(String _sSectionToRemove)
        {
            // first, search for the name
            int i = findSection(_sSectionToRemove);
            if (i == -1)
            {
                // Section to remove not found, do nothing.
                return;
            }
            // second, find the next section
            int j = findNextSection(i + 1);
            if (j == -1)
            {
                // if we are at the end, use size() as second section
                j = m_aList.size();
            }
            // remove all between first and second section
            for (int k = i; k < j; k++)
            {
                m_aList.remove(i);
            }
            // mark the list as changed
            m_bListContainUnsavedChanges = true;
        }

    /**
     * some tests for this class
     */
//    public static void main(String[] args)
//        {
//            String sTempFile = System.getProperty("java.io.tmpdir");
//            sTempFile += "inifile";
//
//
//            IniFile aIniFile = new IniFile(sTempFile);
//            String sValue = aIniFile.getValue("Section", "Key");
//            // insert a new value to a already exist section
//            aIniFile.insertValue("Section", "Key2", "a new value in a existing section");
//            // replace a value
//            aIniFile.insertValue("Section", "Key", "replaced value");
//            // create a new value
//            aIniFile.insertValue("New Section", "Key", "a new key value pair");
//            aIniFile.insertValue("New Section", "Key2", "a new second key value pair");
//
//            String sValue2 = aIniFile.getValue("Section2", "Key");
//
//            aIniFile.removeSection("Section");
//            aIniFile.removeSection("New Section");
//
//            aIniFile.close();
//        }

    /**
     * Enumeration Interface
     * @return true, if there are more Key values
     */
    public boolean hasMoreElements()
        {
            if (m_aEnumerationPos >= 0 &&
                m_aEnumerationPos < m_aList.size())
            {
                return true;
            }
            return false;
        }

    /**
     * Find the next line, which starts with '['
     * @param i start position
     * @return the line where '[' found or -1
     */
    private int findNextSection(int i)
        {
            if (i >= 0)
            {
                while (i < m_aList.size())
                {
                    String sLine =  m_aList.get(i);
                    if (sLine.startsWith("["))
                    {
                        return i;
                    }
                    i++;
                }
            }
            return -1;
        }

    /**
     * Enumeration Interface
     * @return a key without the enveloped '[' ']'
     */
    public Object nextElement()
        {
            int nLineWithSection = findNextSection(m_aEnumerationPos);
            if (nLineWithSection != -1)
            {
                String sSection =  m_aList.get(nLineWithSection);
                m_aEnumerationPos = findNextSection(nLineWithSection + 1);
                sSection = sectionToString(sSection);
                return sSection;
            }
            else
            {
                m_aEnumerationPos = m_aList.size();
            }
            return null;
        }

    /**
     * Helper to count the occurence of Sections
     * @return returns the count of '^['.*']$' Elements
     */
    public int getElementCount()
        {
            int nCount = 0;
            int nPosition = 0;
            while ((nPosition = findNextSection(nPosition)) != -1)
            {
                nCount++;
                nPosition++;
            }
            return nCount;
        }
}

