/*
 * 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.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.List;
import java.util.Map;

/**
 * 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 PublishedExports {

  public String description;
  public long updated;
  public String updatedTime;
  public Map<String, List<ExportEntry>> entries = new HashMap<String, List<ExportEntry>>();

  public PublishedExports() {
  }

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

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

  /**
   * 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
   */
  public boolean isEmpty() {
    return entries.isEmpty();
  }

  public long getUpdated() {
    return updated;
  }

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

  /**
   * 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, List<ExportEntry>>> entries) {
    this.entries = new HashMap<String, List<ExportEntry>>();
    for (Map.Entry<String, List<ExportEntry>> entry : entries) {
      this.entries.put(entry.getKey(), entry.getValue());
    }
  }

  /**
   * Return the values as json string
   *
   * @return
   *
   * @throws IOException
   */
  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 PublishedExports shallowCopy() {
    PublishedExports that = new PublishedExports();
    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();
  }
}
