/*
 * 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.olingo.server.api.prefer;

import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.olingo.commons.api.format.PreferenceName;
import org.apache.olingo.server.api.prefer.Preferences.Return;

/**
 * Provides methods to set values suitable for the Preference-Applied HTTP response header
 * as described in <a href="https://www.ietf.org/rfc/rfc7240.txt">RFC 7240</a>.
 * There are named methods for preferences defined in the OData standard.
 */
public final class PreferencesApplied {

  private static final Set<String> SAFE_PREFERENCE_NAMES = new HashSet<>();
  private Map<String, String> applied;

  private PreferencesApplied() {
    applied = new LinkedHashMap<>();
  }

  /**
   * Gets the applied preferences.
   * @return a map from preference names to preference values
   */
  public Map<String, String> getAppliedPreferences() {
    return Collections.unmodifiableMap(applied);
  }

  /** Returns a string representation that can be used as value of a Preference-Applied HTTP response header. */
  public String toValueString() {
    StringBuilder result = new StringBuilder();
    for (final Map.Entry<String, String> entry : applied.entrySet()) {
      if (result.length() > 0) {
        result.append(',').append(' ');
      }
      final String key = entry.getKey();
      result.append(key);
      if (entry.getValue() != null) {
        final boolean safe = isSafe(key);
        result.append('=')
        .append(safe ? "" : '"')
        .append(entry.getValue().replaceAll("\\\\|\"", "\\\\$0"))
        .append(safe ? "" : '"');
      }
    }
    return result.toString();
  }

  private boolean isSafe(final String key) {
    if (SAFE_PREFERENCE_NAMES.isEmpty()) {
      SAFE_PREFERENCE_NAMES.add(PreferenceName.ALLOW_ENTITY_REFERENCES.getName());
      SAFE_PREFERENCE_NAMES.add(PreferenceName.CALLBACK.getName());
      SAFE_PREFERENCE_NAMES.add(PreferenceName.CONTINUE_ON_ERROR.getName());
      SAFE_PREFERENCE_NAMES.add(PreferenceName.MAX_PAGE_SIZE.getName());
      SAFE_PREFERENCE_NAMES.add(PreferenceName.TRACK_CHANGES.getName());
      SAFE_PREFERENCE_NAMES.add(PreferenceName.RETURN.getName());
      SAFE_PREFERENCE_NAMES.add(PreferenceName.RESPOND_ASYNC.getName());
      SAFE_PREFERENCE_NAMES.add(PreferenceName.WAIT.getName());
    }
    return SAFE_PREFERENCE_NAMES.contains(key);
  }

  @Override
  public String toString() {
    return toValueString();
  }

  /** Initializes the builder. */
  public static Builder with() {
    return new Builder();
  }

  /** Builder of OData serializer options. */
  public static final class Builder {

    private final PreferencesApplied preferencesApplied;

    private Builder() {
      preferencesApplied = new PreferencesApplied();
    }

    /** Sets <code>odata.allow-entityreferences</code>. */
    public Builder allowEntityReferences() {
      add(PreferenceName.ALLOW_ENTITY_REFERENCES.getName(), null);
      return this;
    }

    /** Sets <code>odata.callback</code>. */
    public Builder callback() {
      add(PreferenceName.CALLBACK.getName(), null);
      return this;
    }

    /** Sets <code>odata.continue-on-error</code>. */
    public Builder continueOnError() {
      add(PreferenceName.CONTINUE_ON_ERROR.getName(), null);
      return this;
    }

    /** Sets the value of the applied preference <code>odata.maxpagesize</code>. */
    public Builder maxPageSize(final Integer maxPageSize) {
      add(PreferenceName.MAX_PAGE_SIZE.getName(), Integer.toString(maxPageSize));
      return this;
    }

    /** Sets <code>odata.track-changes</code>. */
    public Builder trackChanges() {
      add(PreferenceName.TRACK_CHANGES.getName(), null);
      return this;
    }

    /** Sets the value of the applied preference <code>return</code>. */
    public Builder returnRepresentation(final Return returnRepresentation) {
      add(PreferenceName.RETURN.getName(), returnRepresentation.name().toLowerCase(Locale.ROOT));
      return this;
    }

    /** Sets <code>odata.respond-async</code>. */
    public Builder respondAsync() {
      add(PreferenceName.RESPOND_ASYNC.getName(), null);
      return this;
    }

    /** Sets the value of the applied preference <code>wait</code>. */
    public Builder waitPreference(final Integer wait) {
      add(PreferenceName.WAIT.getName(), Integer.toString(wait));
      return this;
    }

    /**
     * Sets an arbitrary preference as applied.
     * The preference name is converted to lowercase.
     * The value of this preference may be <code>null</code>.
     * Name and value are not checked for validity.
     * @param name preference name
     * @param value preference value
     */
    public Builder preference(final String name, final String value) {
      if (name != null) {
        add(name.toLowerCase(Locale.ROOT), value);
      }
      return this;
    }

    /** Builds the applied preferences. */
    public PreferencesApplied build() {
      return preferencesApplied;
    }

    private void add(final String name, final String value) {
      if (!preferencesApplied.applied.containsKey(name)) {
        preferencesApplied.applied.put(name, value);
      }
    }
  }
}
