/*
 * Copyright 2015 IBM Corp. All Rights Reserved.
 *
 * Licensed 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 com.ibm.watson.developer_cloud.document_conversion.v1.model;

import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import com.google.gson.JsonObject;

/**
 * Options when indexing a document
 */
public class IndexDocumentOptions {
  /**
   * Builder.
   */
  public static class Builder {
    private JsonObject conversionConfiguration;
    private File document;
    private InputStream documentInputStream;
    private boolean dryRun;
    private IndexConfiguration indexConfiguration;
    private String mediaType;
    private Map<String, String> metadata;

    /**
     * Instantiates a new builder.
     *
     * @param options the options
     */
    private Builder(IndexDocumentOptions options) {
      this.document = options.document;
      this.documentInputStream = options.documentInputStream;
      this.mediaType = options.mediaType;
      this.metadata = options.metadata;
      this.conversionConfiguration = options.convertDocumentConfig;
      this.indexConfiguration = options.indexConfiguration;
      this.dryRun = options.dryRun;
    }

    /**
     * Instantiates a new builder.
     */
    public Builder() {}

    /**
     * Builds the index document options.
     *
     * @return the index document options
     */
    public IndexDocumentOptions build() {
      return new IndexDocumentOptions(this);
    }

    /**
     * Sets the convert document configuration
     *
     * @param convertDocumentConfig Configuration for the convert document phase
     * @return the index document options
     */
    public Builder convertDocumentConfig(JsonObject convertDocumentConfig) {
      this.conversionConfiguration = convertDocumentConfig;
      return this;
    }

    /**
     * Sets the document
     *
     * @param document The document to be converted and indexed
     * @return the index document options
     */
    public Builder document(File document) {
      this.document = document;
      return this;
    }

    /**
     * Sets the document as an input stream and its media type
     * 
     * @param document The document to be converted and indexed
     * @param mediaType The media type of the document
     * @return the index document options
     */
    public Builder document(InputStream document, String mediaType) {
      this.documentInputStream = document;
      this.mediaType = mediaType;
      return this;
    }

    /**
     * Sets the dryRun flag
     *
     * @param dryRun If true, performs a dry run for testing purposes (document won't be indexed),
     *        else to index the document
     * @return the index document options
     */
    public Builder dryRun(Boolean dryRun) {
      this.dryRun = dryRun;
      return this;
    }

    /**
     * Sets the retrieve and rank configuration
     *
     * @param indexConfiguration Configuration for the retrieve and rank service for the indexing
     *        phase
     * @return the index document options
     */
    public Builder indexConfiguration(IndexConfiguration indexConfiguration) {
      this.indexConfiguration = indexConfiguration;
      return this;
    }

    /**
     * Sets the media type
     *
     * @param mediaType The media type of the document to be converted and indexed
     * @return the index document options
     */
    public Builder mediaType(String mediaType) {
      this.mediaType = mediaType;
      return this;
    }


    /**
     * Sets the metadata
     *
     * @param metadata The metadata of the document that will be indexed
     * @return the index document options
     */
    public Builder metadata(Map<String, String> metadata) {
      this.metadata = new HashMap<String,String>();
      this.metadata.putAll(metadata);
      return this;
    }
  }

  private JsonObject convertDocumentConfig;
  private File document;
  private InputStream documentInputStream;
  private Boolean dryRun;
  private IndexConfiguration indexConfiguration;
  private String mediaType;

  private Map<String, String> metadata;

  private IndexDocumentOptions(Builder builder) {
    this.document = builder.document;
    this.documentInputStream = builder.documentInputStream;
    this.mediaType = builder.mediaType;
    this.metadata = builder.metadata;
    this.convertDocumentConfig = builder.conversionConfiguration;
    this.indexConfiguration = builder.indexConfiguration;
    this.dryRun = builder.dryRun;
  }

  /**
   * Gets the configuration for the convert document phase
   *
   * @return conversionConfiguration Configuration for the convert document phase
   */
  public JsonObject convertDocumentConfig() {
    return convertDocumentConfig;
  }

  /**
   * Gets the document
   *
   * @return document The document to be converted and indexed
   */
  public File document() {
    return document;
  }

  /**
   * Gets the dryRun flag
   *
   * @return dryRun If true, performs a dry run for testing purposes (document won't be indexed),
   *         else to index the document
   */
  public Boolean dryRun() {
    return dryRun;
  }

  /**
   * Gets the document as an input stream
   *
   * @return InputStream The document to be converted and indexed
   */
  public InputStream getDocumentInputStream() {
    return documentInputStream;
  }

  /**
   * Gets configuration for the retrieve and rank service for the indexing phase
   *
   * @return indexConfiguration Configuration for the retrieve and rank service for the indexing
   *         phase
   */
  public IndexConfiguration indexConfiguration() {
    return indexConfiguration;
  }

  /**
   * Gets the media type
   *
   * @return mediaType The media type of the document to be converted and indexed
   */
  public String mediaType() {
    return mediaType;
  }

  /**
   * Gets the metadata
   *
   * @return metadata The metadata of the document that will be indexed
   */
  public Map<String, String> metadata() {
    Map<String, String> copy = new HashMap<String,String>();
    copy.putAll(metadata);
    return copy;
  }

  /**
   * New builder.
   *
   * @return the builder
   */
  public Builder newBuilder() {
    return new Builder(this);
  }
}

@@ -4281,32 +4281,33 @@
  HashMap%3CString,
+ 
 String%3E();%0A     
@@ -6489,24 +6489,77 @@
 etadata() %7B%0A
+    if (metadata == null) %7B%0A      return null;%0A    %7D%0A
     Map%3CStri
@@ -6596,16 +6596,17 @@
 %3CString,
+ 
 String%3E(

fix issue when metadata is null