/*
 * 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.ambari.server.stack;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBException;
import javax.xml.bind.UnmarshalException;
import javax.xml.namespace.QName;

import org.apache.ambari.server.state.ConfigHelper;
import org.apache.ambari.server.state.PropertyInfo;
import org.apache.ambari.server.state.stack.ConfigurationXml;
import org.apache.ambari.server.utils.JsonUtils;
import org.apache.ambari.server.utils.XmlUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXParseException;

/**
 * Encapsulates IO operations on a stack definition configuration directory.
 */
public class ConfigurationDirectory extends StackDefinitionDirectory {
  /**
   * Used to unmarshal a stack definition configuration to an object representation
   */
  private static ModuleFileUnmarshaller unmarshaller = new ModuleFileUnmarshaller();

  /**
   * Map of configuration type to configuration module.
   * One entry for each configuration file in this configuration directory.
   */
  private Map<String, ConfigurationModule> configurationModules = new HashMap<>();

  /**
   * Logger instance
   */
  private final static Logger LOG = LoggerFactory.getLogger(ConfigurationDirectory.class);

  /**
   * Properties directory
   */
  protected File propertiesDirFile;

  /**
   * Constructor.
   *
   * @param directoryName  configuration directory name
   */
  public ConfigurationDirectory(String directoryName, String propertiesDirectoryName) {
    super(directoryName);
    if(!StringUtils.isBlank(propertiesDirectoryName)) {
      propertiesDirFile = new File(propertiesDirectoryName);
    }
    parsePath();
  }

  /**
   * Obtain a collection of of configuration modules representing each configuration
   * file contained in this configuration directory.
   *
   * @return collection of configuration modules
   */
  public Collection<ConfigurationModule> getConfigurationModules() {
    return configurationModules.values();
  }

  /**
   * Parse the configuration directory.
   */
  private void parsePath() {
    File[] configFiles = directory.listFiles(StackDirectory.FILENAME_FILTER);
    if (configFiles != null) {
      for (File configFile : configFiles) {
        if (configFile.getName().endsWith(StackDirectory.SERVICE_CONFIG_FILE_NAME_POSTFIX)) {
          String configType = ConfigHelper.fileNameToConfigType(configFile.getName());
          ConfigurationXml config = null;
          try {
            config = unmarshaller.unmarshal(ConfigurationXml.class, configFile);
            ConfigurationInfo configInfo = new ConfigurationInfo(parseProperties(config,
                configFile.getName()), parseAttributes(config));
            ConfigurationModule module = new ConfigurationModule(configType, configInfo);
            configurationModules.put(configType, module);
          } catch (Exception e) {
            String error = null;
            if (e instanceof JAXBException || e instanceof UnmarshalException || e instanceof SAXParseException) {
              error = "Could not parse XML " + configFile + ": " + e;
            } else {
              error = "Could not load configuration for " + configFile;
            }
            config = new ConfigurationXml();
            config.setValid(false);
            config.addError(error);
            ConfigurationInfo configInfo = new ConfigurationInfo(parseProperties(config,
                configFile.getName()), parseAttributes(config));
            configInfo.setValid(false);
            configInfo.addError(error);
            ConfigurationModule module = new ConfigurationModule(configType, configInfo);
            configurationModules.put(configType, module);
          }
        }
      }
    }
  }

  /**
   * Parse a configurations properties.
   *
   * @param configuration  object representation of a configuration file
   * @param fileName       configuration file name
   *
   * @return  collection of properties
   */
  private Collection<PropertyInfo> parseProperties(ConfigurationXml configuration, String fileName) {
  List<PropertyInfo> props = new ArrayList<>();
  for (PropertyInfo pi : configuration.getProperties()) {
    pi.setFilename(fileName);
    if(pi.getPropertyTypes().contains(PropertyInfo.PropertyType.VALUE_FROM_PROPERTY_FILE)) {
      if(propertiesDirFile != null && propertiesDirFile.exists() && propertiesDirFile.isDirectory() ) {
        String propertyFileName = pi.getPropertyValueAttributes().getPropertyFileName();
        String propertyFileType = pi.getPropertyValueAttributes().getPropertyFileType();
        String propertyFilePath = propertiesDirFile.getAbsolutePath() + File.separator + propertyFileName;
        File propertyFile = new File(propertyFilePath);
        if (propertyFile.exists() && propertyFile.isFile()) {
          try {
            String propertyValue = FileUtils.readFileToString(propertyFile);
            boolean valid = true;
            switch (propertyFileType.toLowerCase()) {
              case "xml" :
                if (!XmlUtils.isValidXml(propertyValue)) {
                  valid = false;
                  LOG.error("Failed to load value from property file. Property file {} is not a valid XML file", propertyFilePath);
                }
                break;
              case "json":
                if (!JsonUtils.isValidJson(propertyValue)) {
                  valid = false;
                  LOG.error("Failed to load value from property file. Property file {} is not a valid JSON file", propertyFilePath);
                }
                break;
              case "text":
                // fallthrough
              default:
                // no validity check
                break;
            }
            if (valid) {
              pi.setValue(propertyValue);
            }
          } catch (IOException e) {
            LOG.error("Failed to load value from property file {}. Error Message {}", propertyFilePath, e.getMessage());
          }
        } else {
          LOG.error("Failed to load value from property file. Properties file {} does not exist", propertyFilePath);
        }
      } else {
        LOG.error("Failed to load value from property file. Properties directory {} does not exist", propertiesDirFile.getAbsolutePath());
      }
    }
    props.add(pi);
  }
  return props; }

  /**
   * Parse a configurations type attributes.
   *
   * @param configuration  object representation of a configuration file
   *
   * @return  collection of attributes for the configuration type
   */
  private Map<String, String> parseAttributes(ConfigurationXml configuration) {
    Map<String, String> attributes = new HashMap<>();
    for (Map.Entry<QName, String> attribute : configuration.getAttributes().entrySet()) {
      attributes.put(attribute.getKey().getLocalPart(), attribute.getValue());
    }
    return attributes;
  }
}
