/*******************************************************************************
 * Copyright (c) 2004, 2005 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.ws.internal.explorer.platform.uddi.datamodel;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;
import java.util.Vector;
import javax.servlet.ServletContext;
import org.eclipse.wst.ws.internal.datamodel.BasicModel;
import org.eclipse.wst.ws.internal.datamodel.Element;
import org.eclipse.wst.ws.internal.explorer.platform.constants.ModelConstants;
import org.eclipse.wst.ws.internal.explorer.platform.uddi.constants.UDDIModelConstants;
import org.eclipse.wst.ws.internal.explorer.platform.util.HTMLUtils;
import org.eclipse.wst.ws.internal.model.v10.taxonomy.Category;
import org.eclipse.wst.ws.internal.model.v10.taxonomy.Taxonomy;
import org.uddi4j.util.KeyedReference;

public class CategoryModel extends BasicModel
{
  private ServletContext application_;
  private String defaultDataFile_;
  private Hashtable categoryElements_;
  private String columnDelimiter_;
  private String stringDelimiter_;
  private String categoryKey_;
  private boolean checked_;
  private String displayName_;
  private String tModelKey_;
  private Throwable errorException_;
  
  // Return codes for loading and saving category data.
  public static final byte OPERATION_SUCCESSFUL = 0x00;
  public static final byte ERROR_FILE = 0x01;
  public static final byte ERROR_SECURITY = 0x02;
  public static final byte ERROR_ENCODING = 0x03;
  public static final byte ERROR_IO = 0x04;
  public static final byte ERROR_CATEGORY_KEY = 0x05;
  
  private final String defaultColumnDelimiter_ = "#";
  private final String defaultStringDelimiter_ = "\"";
  
  public CategoryModel()
  {
    super("categories");
    application_ = null;
	defaultDataFile_ = null;
    columnDelimiter_ = defaultColumnDelimiter_;
    stringDelimiter_ = defaultStringDelimiter_;
    categoryElements_ = null;
    categoryKey_ = null;
    checked_ = true;
    displayName_ = null;
    tModelKey_ = null;
    errorException_ = null;
  }
  
  /**
   * CategoryModels load their data from the file named via the
   * {@link #setDefaultDataFile(String)} method. The data file
   * name is interpretted as either a physical pathname or a
   * context-root relative pathname depending on whether the
   * servlet context or "application" is null (default) or not.
   * @param application The application context, null by default.
   * Value can be the ServletContext of the WSExplorer or null.
   */
  public final void setServletContext(ServletContext application)
  {
	application_ = application;
  }
  
  public final void setDefaultDataFile(String defaultDataFile)
  {
    defaultDataFile_ = defaultDataFile;
  }

  public final void setCategoryKey(String categoryKey)
  {
    categoryKey_ = categoryKey;
  }
  
  public final String getCategoryKey()
  {
    return categoryKey_;
  }
  
  public final void setColumnDelimiter(String columnDelimiter)
  {
    columnDelimiter_ = columnDelimiter;
  }
  
  public final String getColumnDelimiter()
  {
    return columnDelimiter_;
  }
  
  public final void setStringDelimiter(String stringDelimiter)
  {
    stringDelimiter_ = stringDelimiter;
  }
  
  public final String getStringDelimiter()
  {
    return stringDelimiter_;
  }
  
  public final void enableChecked(boolean isChecked)
  {
    checked_ = isChecked;
  }
  
  public final boolean isChecked()
  {
    return checked_;
  }
  
  public final void setDisplayName(String displayName)
  {
    displayName_ = displayName;
  }
  
  public final String getDisplayName()
  {
    return displayName_;
  }
  
  public final void setTModelKey(String tModelKey)
  {
    tModelKey_ = tModelKey;
  }
  
  public final String getTModelKey()
  {
    return tModelKey_;
  }
  
  public final boolean isDataLoaded()
  {
    return (categoryElements_ != null);
  }
  
  public final Throwable getErrorException()
  {
    return errorException_;
  }
  
  private final boolean isEnclosedInQuotes(String string)
  {
    return string.startsWith("\"") && string.endsWith("\"");
  }

  public final void loadFromTaxonomy(Taxonomy taxonomy)
  {
    String name = taxonomy.getName();
    CategoryElement root = new CategoryElement(name,null,this);
    setRootElement(root);
    categoryElements_ = new Hashtable();
    for (Iterator it = taxonomy.getCategory().iterator(); it.hasNext();)
    {
      addCategory(root, (Category)it.next());
    }
  }

  private void addCategory(CategoryElement parent, Category category)
  {
    String keyName = category.getName();
    String keyValue = category.getCode();
    CategoryElement child = new CategoryElement(keyName,new KeyedReference(keyName,keyValue,tModelKey_),this);
    parent.connect(child,UDDIModelConstants.REL_SUBCATEGORIES,ModelConstants.REL_OWNER);
    categoryElements_.put(keyValue, child);   
    for (Iterator it = category.getCategory().iterator(); it.hasNext();)
    {
      addCategory(child, (Category)it.next());
    }
  }

  public final byte loadFromDefaultDataFile()
  {
    try
    {
      if (defaultDataFile_ == null)
        throw new FileNotFoundException();
	  BufferedReader br = null;
	  if (application_ == null)
		br = new BufferedReader(new InputStreamReader(new FileInputStream(defaultDataFile_),HTMLUtils.UTF8_ENCODING));
	  else
	    br = new BufferedReader(new InputStreamReader(application_.getResourceAsStream(defaultDataFile_),HTMLUtils.UTF8_ENCODING));
      return loadData(br);
    }
    catch (FileNotFoundException e)
    {
      errorException_ = e;
      return ERROR_FILE;
    }
    catch (SecurityException e)
    {
      errorException_ = e;
      return ERROR_SECURITY;
    }
    catch (UnsupportedEncodingException e)
    {
      errorException_ = e;
      return ERROR_ENCODING;
    }
  }
  
  public final byte loadFromDelimiterFile()
  {
    // Get the associated .properties file and set the delimiters. The defaultDataFile_ is set to the delimiter file in this case.
    // The properties file contains the following keys:
    // wsad.dataFile - location of the category data file.
    // wsad.checked - whether or not the category is checked.
    // wsad.name - the display name of the category.
    // column.delimiter - the delimiter character used for separating columns.
    // string.delimiter - the delimiter character used to encapsulate data such that column delimiter characters are treated as data.
    try
    {
      Properties p = new Properties();
      InputStream fin = null;
	  if (application_ == null)
	    fin = new FileInputStream(defaultDataFile_);
	  else
		fin = application_.getResourceAsStream(defaultDataFile_);
      p.load(fin);
      fin.close();
      columnDelimiter_ = p.getProperty("column.delimiter");
      stringDelimiter_ = p.getProperty("string.delimiter");
      defaultDataFile_ = p.getProperty("wsad.dataFile");
      return loadFromDefaultDataFile();
    }
    catch (FileNotFoundException e)
    {
      errorException_ = e;
      return ERROR_FILE;
    }
    catch (SecurityException e)
    {
      errorException_ = e;
      return ERROR_SECURITY;
    }
    catch (IOException e)
    {
      errorException_ = e;
      return ERROR_IO;
    }        
  }
  
  public final byte loadData(BufferedReader br)
  {
    errorException_ = null;
    CategoryElement rootElement = null;
    categoryElements_ = new Hashtable();
    byte returnCode = OPERATION_SUCCESSFUL;
    String line = null;
    int lineNumber = 0;
    try
    {
      char columnDelimiterChar = columnDelimiter_.charAt(0);
      char stringDelimiterChar = stringDelimiter_.charAt(0);
      Vector values = new Vector();
      while((line = br.readLine()) != null)
      {
        lineNumber++;
        // Ignore blank lines.
        if (line.trim().length() == 0)
          continue;
        int index = 0;
        int length = line.length();
        boolean inStringDelimiters = false;
        values.removeAllElements();
        StringBuffer currentToken = new StringBuffer();
        while (index < length)
        {
          char currentChar = line.charAt(index);
          if (inStringDelimiters)
          {
            // In quote so ignoring delimiters
            if (currentChar == stringDelimiterChar)
            {
              if (index < length - 1)
              {
                // currentChar could be a closing string delimiter or escape
                // Need to look ahead to be sure...
                char followingChar = line.charAt(index + 1);
                if (followingChar == stringDelimiterChar)
                {
                  // There is an escaped quote
                  currentToken.append(stringDelimiterChar);
                  // jump forward two characters.
                  index += 2;
                }
                else
                {
                  // There was a closing string delimiter...jump forward to the next delimiter
                  inStringDelimiters = false;
                  //look for the next column delimiter character
                  int nextDelimiter = line.indexOf(columnDelimiterChar, index);
                  if (nextDelimiter == -1)
                  {
                    // There were no more delimiters so break out of the loop
                    break;
                  }
                  else
                  {
                    values.addElement(currentToken.toString());
                    //values[tokenCount++] = currentToken.toString();
                    currentToken.setLength(0);
                    inStringDelimiters = false;
                    index = nextDelimiter + 1;
                  }
                }
              }
              else
              {
                // This is the last character and it's a closing string delimiter.
                index++;
                inStringDelimiters = false;
              }
            }
            else
            {
              currentToken.append(currentChar);
              index++;
            }
          }
          else if (currentChar == columnDelimiterChar)
          {
            // There was a delimiter outside of quotes
            values.addElement(currentToken.toString());
            //values[tokenCount++] = currentToken.toString();
            currentToken.setLength(0);
            index++;
          }
          else if (currentChar == stringDelimiterChar)
          {
            // A quote appearing outside of quotes must be a opening quote
            inStringDelimiters = true;
            index++;
          }
          else
          {
            // There is a normal char outside of quotes
            currentToken.append(currentChar);
            index++;
          }
        }
        // Expect token count to be values.length - 1 at this point if everything is ok
        if (inStringDelimiters)
        {
          br.close();
          throw new ParseException(line,lineNumber);
        }
        
        // Add the final token.
        values.addElement(currentToken.toString());

        // 3 columns format. From left to right, these are:
        // 1) category's key value
        // 2) category's key name
        // 3) category's parent key value
        // Convert to 4 columns format.
        if (values.size() == 3)
        {
          if (categoryKey_ != null)
            values.insertElementAt(categoryKey_, 0);
          else
            values.insertElementAt(tModelKey_, 0);
        }

        // 4 columns format. From left to right, these are:
        // 1) type of category (categoryKey)
        // 2) category's key value
        // 3) category's key name
        // 4) category's parent key value
        if (values.size() == 4)
        {
          String categoryKey = (String)values.elementAt(0);
          if (categoryKey_ == null)
            categoryKey_ = categoryKey;
          else if (!categoryKey_.equals(categoryKey))
            throw new Exception(categoryKey);
          String keyValue = (String)values.elementAt(1);
          String keyName = (String)values.elementAt(2);
          String parentKeyValue = (String)values.elementAt(3);
          if (rootElement == null)
          {
            rootElement = new CategoryElement(displayName_,null,this);
            setRootElement(rootElement);
          }
          if (isEnclosedInQuotes(keyName))
            keyName = keyName.substring(1,keyName.length()-1);
          // Check if the CategoryElement already exists. If it does, refresh the Category.
          CategoryElement categoryElement = (CategoryElement)categoryElements_.get(keyValue);
          if (categoryElement != null)
            categoryElement.updateCategory(keyName,keyValue,tModelKey_);
          else
            categoryElement = new CategoryElement(keyName,new KeyedReference(keyName,keyValue,tModelKey_),this);
          Element parentElement;
          if (parentKeyValue.equals(keyValue))
            parentElement = rootElement;
          else
            parentElement = (Element)categoryElements_.get(parentKeyValue);
          if (parentElement == null)
          {
            parentElement = new CategoryElement("temp",new KeyedReference("",parentKeyValue,tModelKey_),this);
            categoryElements_.put(parentKeyValue,parentElement);
          }
          else
            parentElement.connect(categoryElement,UDDIModelConstants.REL_SUBCATEGORIES,ModelConstants.REL_OWNER);
          categoryElements_.put(keyValue,categoryElement);          
        }
        else
        {
          br.close();
          throw new ParseException(line,lineNumber);
        }
      }
      br.close();
      return returnCode;
    }
    catch (IOException e)
    {
      errorException_ = e;
      returnCode = ERROR_IO;
    }
    catch (ParseException e)
    {
      errorException_ = e;
      returnCode = ERROR_FILE;
    }
    catch (Exception e)
    {
      errorException_ = e;
      returnCode = ERROR_CATEGORY_KEY;
    }
    categoryElements_ = null;
    return returnCode;
  }
  
  private final void saveData(PrintWriter pw,CategoryElement categoryElement,CategoryElement parentElement,boolean isFirst)
  {
    // File format:
    // <categoryKey>#<keyValue>#<keyName>#<parentKeyValue>
    KeyedReference kr = categoryElement.getCategory();
    // Check if this is not the root element.
    if (kr != null)
    {
      String keyName = kr.getKeyName();
      String keyValue = kr.getKeyValue();
      String parentKeyValue;
      if (parentElement == null)
        parentKeyValue = keyValue;
      else
      {
        KeyedReference parentKr = parentElement.getCategory();
        // Check if the parent is the root element.
        if (parentKr == null)
          parentKeyValue = keyValue;
        else
          parentKeyValue = parentKr.getKeyValue();
      }
      if (!isFirst)
        pw.println();
      else
        isFirst = false;
      pw.print(mangle(categoryKey_));
      pw.print(columnDelimiter_);
      pw.print(mangle(keyValue));
      pw.print(columnDelimiter_);
      pw.print(mangle(keyName));
      pw.print(columnDelimiter_);
      pw.print(mangle(parentKeyValue));
    }
    Enumeration e = categoryElement.getElements(UDDIModelConstants.REL_SUBCATEGORIES);
    if (e != null)
    {
      while (e.hasMoreElements())
        saveData(pw,(CategoryElement)e.nextElement(),categoryElement,isFirst);
    }
  }
  
  // Mangle an input string if it contains default column delimiter characters by surrounding it with the string delimiters.
  private final String mangle(String input)
  {
    if (input != null && input.indexOf(columnDelimiter_) != -1)
    {
      StringBuffer s = new StringBuffer(input);
      s.insert(0,stringDelimiter_).append(stringDelimiter_);
      return s.toString();
    }
    return input;
  }
  
  public final byte saveData(String fileName)
  {
    // The fileName should already be URLEncoded.
    byte returnCode = OPERATION_SUCCESSFUL;
    errorException_ = null;
    if (isDataLoaded())
    {
      try
      {
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fileName),HTMLUtils.UTF8_ENCODING),true);
        CategoryElement rootElement = (CategoryElement)getRootElement();
        saveData(pw,rootElement,null,true);
        pw.flush();
        pw.close();
        // Save the properties file.
        Properties p = new Properties();
        p.setProperty("wsad.dataFile",fileName);
        p.setProperty("wsad.checked",String.valueOf(checked_));
        p.setProperty("wsad.name",displayName_);
        p.setProperty("column.delimiter",columnDelimiter_);
        p.setProperty("string.delimiter",stringDelimiter_);
        StringBuffer propertiesFileName = new StringBuffer(fileName.substring(0,fileName.lastIndexOf('.')));
        propertiesFileName.append(".properties");
        FileOutputStream fout = new FileOutputStream(propertiesFileName.toString());
        p.store(fout,null);
        fout.close();
      }
      catch (FileNotFoundException e)
      {
        errorException_ = e;
        returnCode = ERROR_FILE;
      }
      catch (SecurityException e)
      {
        errorException_ = e;
        returnCode = ERROR_SECURITY;
      }
      catch (UnsupportedEncodingException e)
      {
        errorException_ = e;
        returnCode = ERROR_ENCODING;
      }
      catch (IOException e)
      {
        errorException_ = e;
        returnCode = ERROR_IO;
      }
    }
    return returnCode;
  }
  
  public String toString()
  {
    return displayName_;
  }
}
