/*
 * 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.
 */

package org.apache.uima.resource.metadata.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.uima.UIMA_IllegalArgumentException;
import org.apache.uima.resource.metadata.ConfigurationGroup;
import org.apache.uima.resource.metadata.ConfigurationParameter;
import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations;
import org.apache.uima.util.InvalidXMLException;
import org.apache.uima.util.XMLParser;
import org.apache.uima.util.XMLizable;
import org.apache.uima.util.impl.Constants;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.helpers.AttributesImpl;

/**
 * 
 * 
 */
public class ConfigurationParameterDeclarations_impl extends MetaDataObject_impl
        implements ConfigurationParameterDeclarations {

  static final long serialVersionUID = -2248322904617280983L;

  static final ConfigurationGroup[] EMPTY_CONFIG_GROUP_ARRAY = new ConfigurationGroup[0];

  /** Configuration Parameters that are not in any group */
  private ConfigurationParameter[] mConfigurationParameters = Constants.EMPTY_CONFIG_PARM_ARRAY;

  /** Configuration Groups */
  private ConfigurationGroup[] mConfigurationGroups = EMPTY_CONFIG_GROUP_ARRAY;

  /** Parameters common to all groups */
  private ConfigurationParameter[] mCommonParameters = Constants.EMPTY_CONFIG_PARM_ARRAY;

  /** Name of the default group */
  private String mDefaultGroupName;

  /** Configuration parameter search strategy */
  private String mSearchStrategy;

  /**
   * @see ConfigurationParameterDeclarations#getConfigurationParameters()
   */
  @Override
  public ConfigurationParameter[] getConfigurationParameters() {
    return mConfigurationParameters;
  }

  /**
   * @see ConfigurationParameterDeclarations#setConfigurationParameters(ConfigurationParameter[])
   */
  @Override
  public void setConfigurationParameters(ConfigurationParameter[] aParams) {
    if (aParams == null) {
      throw new UIMA_IllegalArgumentException(UIMA_IllegalArgumentException.ILLEGAL_ARGUMENT,
              new Object[] { "null", "aParams", "setConfigurationParameters" });
    }
    mConfigurationParameters = aParams;
  }

  /**
   * @see ConfigurationParameterDeclarations#getCommonParameters()
   */
  @Override
  public ConfigurationParameter[] getCommonParameters() {
    return mCommonParameters;
  }

  /**
   * @see ConfigurationParameterDeclarations#getConfigurationGroups()
   */
  @Override
  public ConfigurationGroup[] getConfigurationGroups() {
    return mConfigurationGroups;
  }

  /**
   * @see ConfigurationParameterDeclarations#getDefaultGroupName()
   */
  @Override
  public String getDefaultGroupName() {
    return mDefaultGroupName;
  }

  /**
   * @see ConfigurationParameterDeclarations#getSearchStrategy()
   */
  @Override
  public String getSearchStrategy() {
    return mSearchStrategy;
  }

  /**
   * @see ConfigurationParameterDeclarations#setCommonParameters(ConfigurationParameter[])
   */
  @Override
  public void setCommonParameters(ConfigurationParameter... aParams) {
    if (aParams == null) {
      throw new UIMA_IllegalArgumentException(UIMA_IllegalArgumentException.ILLEGAL_ARGUMENT,
              new Object[] { "null", "aParams", "setCommonParameters" });
    }
    mCommonParameters = aParams;
  }

  /**
   * @see ConfigurationParameterDeclarations#setConfigurationGroups(ConfigurationGroup[])
   */
  @Override
  public void setConfigurationGroups(ConfigurationGroup... aGroups) {
    if (aGroups == null) {
      throw new UIMA_IllegalArgumentException(UIMA_IllegalArgumentException.ILLEGAL_ARGUMENT,
              new Object[] { "null", "aGroups", "setConfigurationGroups" });
    }
    mConfigurationGroups = aGroups;
  }

  /**
   * @see ConfigurationParameterDeclarations#setDefaultGroupName(String)
   */
  @Override
  public void setDefaultGroupName(String aGroupName) {
    mDefaultGroupName = aGroupName;
  }

  /**
   * @see ConfigurationParameterDeclarations#setSearchStrategy(java.lang.String)
   */
  @Override
  public void setSearchStrategy(String aStrategy) {
    mSearchStrategy = aStrategy;
  }

  /**
   * @see ConfigurationParameterDeclarations#getConfigurationParameter(String, String)
   */
  @Override
  public ConfigurationParameter getConfigurationParameter(String aGroupName, String aParamName) {
    if (aGroupName == null) {
      // look in list of params that are in no group
      ConfigurationParameter[] params = getConfigurationParameters();
      return _getConfigurationParameter(params, aParamName);
    } else {
      // look in common parameters
      ConfigurationParameter[] commonParams = getCommonParameters();
      ConfigurationParameter p = _getConfigurationParameter(commonParams, aParamName);
      if (p == null) {
        // find group
        ConfigurationGroup[] groups = getConfigurationGroupDeclarations(aGroupName);
        for (int i = 0; i < groups.length; i++) {
          ConfigurationParameter[] paramsInGroup = groups[i].getConfigurationParameters();
          p = _getConfigurationParameter(paramsInGroup, aParamName);
          if (p != null) {
            break;
          }
        }
      }
      return p;
    }
  }

  /**
   * @see ConfigurationParameterDeclarations#getConfigurationGroupDeclarations(String)
   */
  @Override
  public ConfigurationGroup[] getConfigurationGroupDeclarations(String aGroupName) {
    List<ConfigurationGroup> results = new ArrayList<>();
    ConfigurationGroup[] grps = getConfigurationGroups();
    if (grps != null) {
      for (int i = 0; i < grps.length; i++) {
        String[] names = grps[i].getNames();
        for (int j = 0; j < names.length; j++) {
          if (aGroupName.equals(names[j])) {
            results.add(grps[i]);
            break;
          }
        }
      }
    }
    ConfigurationGroup[] resultArr = new ConfigurationGroup[results.size()];
    results.toArray(resultArr);
    return resultArr;
  }

  /**
   * 
   * @see ConfigurationParameterDeclarations#addConfigurationParameter(ConfigurationParameter)
   */
  @Override
  public void addConfigurationParameter(ConfigurationParameter aConfigurationParameter) {
    ConfigurationParameter[] current = getConfigurationParameters();
    ConfigurationParameter[] newArr = new ConfigurationParameter[current.length + 1];
    System.arraycopy(current, 0, newArr, 0, current.length);
    newArr[current.length] = aConfigurationParameter;
    setConfigurationParameters(newArr);
  }

  /**
   * 
   * @see ConfigurationParameterDeclarations#removeConfigurationParameter(ConfigurationParameter)
   */
  @Override
  public void removeConfigurationParameter(ConfigurationParameter aConfigurationParameter) {
    ConfigurationParameter[] current = getConfigurationParameters();
    for (int i = 0; i < current.length; i++) {
      if (current[i] == aConfigurationParameter) {
        ConfigurationParameter[] newArr = new ConfigurationParameter[current.length - 1];
        System.arraycopy(current, 0, newArr, 0, i);
        System.arraycopy(current, i + 1, newArr, i, current.length - i - 1);
        setConfigurationParameters(newArr);
        break;
      }
    }
  }

  /**
   * @see ConfigurationParameterDeclarations#addConfigurationParameter(ConfigurationParameter)
   */
  @Override
  public void addCommonParameter(ConfigurationParameter aConfigurationParameter) {
    ConfigurationParameter[] current = getCommonParameters();
    ConfigurationParameter[] newArr = new ConfigurationParameter[current.length + 1];
    System.arraycopy(current, 0, newArr, 0, current.length);
    newArr[current.length] = aConfigurationParameter;
    setCommonParameters(newArr);
  }

  /**
   * @see ConfigurationParameterDeclarations#removeConfigurationParameter(ConfigurationParameter)
   */
  @Override
  public void removeCommonParameter(ConfigurationParameter aConfigurationParameter) {
    ConfigurationParameter[] current = getCommonParameters();
    for (int i = 0; i < current.length; i++) {
      if (current[i] == aConfigurationParameter) {
        ConfigurationParameter[] newArr = new ConfigurationParameter[current.length - 1];
        System.arraycopy(current, 0, newArr, 0, i);
        System.arraycopy(current, i + 1, newArr, i, current.length - i - 1);
        setCommonParameters(newArr);
        break;
      }
    }
  }

  /**
   * @see ConfigurationParameterDeclarations#addConfigurationGroup(ConfigurationGroup)
   */
  @Override
  public void addConfigurationGroup(ConfigurationGroup aConfigurationGroup) {
    ConfigurationGroup[] current = getConfigurationGroups();
    ConfigurationGroup[] newArr = new ConfigurationGroup[current.length + 1];
    System.arraycopy(current, 0, newArr, 0, current.length);
    newArr[current.length] = aConfigurationGroup;
    setConfigurationGroups(newArr);
  }

  /**
   * @see ConfigurationParameterDeclarations#removeConfigurationGroup(ConfigurationGroup)
   */
  @Override
  public void removeConfigurationGroup(ConfigurationGroup aConfigurationGroup) {
    ConfigurationGroup[] current = getConfigurationGroups();
    for (int i = 0; i < current.length; i++) {
      if (current[i] == aConfigurationGroup) {
        ConfigurationGroup[] newArr = new ConfigurationGroup[current.length - 1];
        System.arraycopy(current, 0, newArr, 0, i);
        System.arraycopy(current, i + 1, newArr, i, current.length - i - 1);
        setConfigurationGroups(newArr);
        break;
      }
    }
  }

  /* Utility method */
  protected ConfigurationParameter _getConfigurationParameter(ConfigurationParameter[] aParams,
          String aName) {
    if (aParams != null) {
      for (int i = 0; i < aParams.length; i++) {
        if (aName.equals(aParams[i].getName())) {
          return aParams[i];
        }
      }
    }
    return null;
  }

  /**
   * Overridden to provide custom XMLization.
   * 
   * @see org.apache.uima.util.XMLizable#buildFromXMLElement(org.w3c.dom.Element,
   *      org.apache.uima.util.XMLParser)
   */
  @Override
  public void buildFromXMLElement(Element aElement, XMLParser aParser,
          XMLParser.ParsingOptions aOptions) throws InvalidXMLException {
    // read defaultGroup and searchStrategy from attributes
    String defaultGroup = aElement.getAttribute("defaultGroup");
    if (defaultGroup.length() > 0) {
      setDefaultGroupName(defaultGroup);
    } else {
      setDefaultGroupName(null);
    }

    String searchStrategy = aElement.getAttribute("searchStrategy");
    if (searchStrategy.length() > 0) {
      setSearchStrategy(searchStrategy);
    } else {
      setSearchStrategy(null);
    }

    // read parameters, commonParameters, and configurationGroups
    List<XMLizable> params = new ArrayList<>();
    List<XMLizable> groups = new ArrayList<>();
    NodeList childNodes = aElement.getChildNodes();
    for (int i = 0; i < childNodes.getLength(); i++) {
      Node curNode = childNodes.item(i);
      if (curNode instanceof Element) {
        Element elem = (Element) curNode;
        if ("configurationParameter".equals(elem.getTagName())) {
          params.add(aParser.buildObject(elem, aOptions));
        } else if ("commonParameters".equals(elem.getTagName())) {
          final PropertyXmlInfo commonParametersPropInfo = new PropertyXmlInfo("commonParameters");
          readPropertyValueFromXMLElement(commonParametersPropInfo, elem, aParser, aOptions);
        } else if ("configurationGroup".equals(elem.getTagName())) {
          groups.add(aParser.buildObject(elem, aOptions));
        } else {
          throw new InvalidXMLException(InvalidXMLException.UNKNOWN_ELEMENT,
                  new Object[] { elem.getTagName() });
        }
      }
    }
    ConfigurationParameter[] paramArr = new ConfigurationParameter[params.size()];
    params.toArray(paramArr);
    setConfigurationParameters(paramArr);
    ConfigurationGroup[] groupArr = new ConfigurationGroup[groups.size()];
    groups.toArray(groupArr);
    setConfigurationGroups(groupArr);
  }

//@formatter:off
  /**
   * Overridden to return defaultGroup and searchStrategy as XML attributes.
   * 
   * 9/2013: superclasses don't have this method, so can't be overridden.
   * 9/2013: method never called
   * @return - 
   */
//@formatter:on
  protected String getXMLAttributeString() {
    StringBuffer buf = new StringBuffer();
    if (getDefaultGroupName() != null) {
      buf.append("defaultGroup = \"");
      buf.append(getDefaultGroupName());
      buf.append('"');
    }
    if (getSearchStrategy() != null) {
      if (buf.length() > 0) {
        buf.append(' ');
      }
      buf.append("searchStrategy = \"");
      buf.append(getSearchStrategy());
      buf.append('"');
    }
    return buf.toString();
  }

  /**
   * @see MetaDataObject_impl#getXMLAttributes()
   */
  @Override
  protected AttributesImpl getXMLAttributes() {
    AttributesImpl attrs = new AttributesImpl();
    if ((getDefaultGroupName() != null) && (!getDefaultGroupName().equals(""))) {
      attrs.addAttribute("", "defaultGroup", "defaultGroup", "string", getDefaultGroupName());
    }
    if ((getSearchStrategy() != null) && (!getSearchStrategy().equals(""))) {
      attrs.addAttribute("", "searchStrategy", "searchStrategy", "string", getSearchStrategy());
    }
    return attrs;
  }

  /**
   * @see MetaDataObject_impl#getXmlizationInfo()
   */
  @Override
  protected XmlizationInfo getXmlizationInfo() {
    // NOTE: custom XMLization is used for reading. This information
    // is only used for writing.
    return new XmlizationInfo("configurationParameters",
            new PropertyXmlInfo[] { new PropertyXmlInfo("configurationParameters", null),
                new PropertyXmlInfo("commonParameters", "commonParameters"),
                new PropertyXmlInfo("configurationGroups", null) });
  }
}
