/*
 * 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.slider.core.registry.docstore;

import org.apache.hadoop.conf.Configuration;
import org.apache.slider.common.tools.ConfigHelper;
import org.apache.slider.core.exceptions.BadConfigException;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonSerialize;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * JSON-serializable description of a published key-val configuration.
 * 
 * The values themselves are not serialized in the external view; they have
 * to be served up by the far end
 */
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class PublishedConfiguration {

  public String description;
  public long updated;
  
  public String updatedTime;

  public Map<String, String> entries = new HashMap<String, String>();

  public PublishedConfiguration() {
  }

  /**
   * build an empty published configuration 
   * @param description configuration description
   */
  public PublishedConfiguration(String description) {
    this.description = description;
  }

  /**
   * Build a configuration from the entries
   * @param description configuration description
   * @param entries entries to put
   */
  public PublishedConfiguration(String description,
      Iterable<Map.Entry<String, String>> entries) {
    this.description = description;
    putValues(entries);
  }

  /**
   * Build a published configuration, using the keys from keysource,
   * but resolving the values from the value source, via Configuration.get()
   * @param description configuration description
   * @param keysource source of keys
   * @param valuesource source of values
   */
  public PublishedConfiguration(String description,
      Iterable<Map.Entry<String, String>> keysource,
      Configuration valuesource) {
    this.description = description;
    putValues(ConfigHelper.resolveConfiguration(keysource, valuesource));
  }

  
  /**
   * Is the configuration empty. This means either that it has not
   * been given any values, or it is stripped down copy set down over the
   * wire.
   * @return true if it is empty
   */
  public boolean isEmpty() {
    return entries.isEmpty();
  }


  public void setUpdated(long updated) {
    this.updated = updated;
    this.updatedTime = new Date(updated).toString();
  }

  public long getUpdated() {
    return updated;
  }

  /**
   * Set the values from an iterable (this includes a Hadoop Configuration
   * and Java properties object).
   * Any existing value set is discarded
   * @param entries entries to put
   */
  public void putValues(Iterable<Map.Entry<String, String>> entries) {
    this.entries = new HashMap<String, String>();
    for (Map.Entry<String, String> entry : entries) {
      this.entries.put(entry.getKey(), entry.getValue());
    }
    
  }

  /**
   * Convert to Hadoop XML
   * @return the configuration as a Hadoop Configuratin
   */
  public Configuration asConfiguration() {
    Configuration conf = new Configuration(false);
    try {
      ConfigHelper.addConfigMap(conf, entries, "");
    } catch (BadConfigException e) {
      // triggered on a null value; switch to a runtime (and discard the stack)
      throw new RuntimeException(e.toString());
    }
    return conf;
  }
  
  public String asConfigurationXML() throws IOException {
    return ConfigHelper.toXml(asConfiguration());
  }

  /**
   * Convert values to properties
   * @return a property file
   */
  public Properties asProperties() {
    Properties props = new Properties();
    props.putAll(entries);
    return props;
  }

  /**
   * Return the values as json string
   * @return the JSON representation
   * @throws IOException marshalling failure
   */
  public String asJson() throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
    String json = mapper.writeValueAsString(entries);
    return json;
  }


  /**
   * This makes a copy without the nested content -so is suitable
   * for returning as part of the list of a parent's values
   * @return the copy
   */
  public PublishedConfiguration shallowCopy() {
    PublishedConfiguration that = new PublishedConfiguration();
    that.description = this.description;
    that.updated = this.updated;
    that.updatedTime = this.updatedTime;
    return that;
  }

  @Override
  public String toString() {
    final StringBuilder sb =
        new StringBuilder("PublishedConfiguration{");
    sb.append("description='").append(description).append('\'');
    sb.append(" entries = ").append(entries.size());
    sb.append('}');
    return sb.toString();
  }

  /**
   * Create an outputter for a given format
   * @param format format to use
   * @return an instance of output
   */
  public PublishedConfigurationOutputter createOutputter(ConfigFormat format) {
    return PublishedConfigurationOutputter.createOutputter(format, this);
  }
}
