/*
 * 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.drill.common.map;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;

import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * A special type of {@link Map} with {@link String}s as keys, and the case of a key is ignored for operations involving
 * keys like {@link #put}, {@link #get}, etc. The keys are stored and retrieved in lower case. Use the static factory
 * methods to create instances of this class (e.g. {@link #newConcurrentMap}).
 *
 * @param <VALUE> the type of values to be stored in the map
 */
public class CaseInsensitiveMap<VALUE> implements Map<String, VALUE> {

  /**
   * Returns a new instance of {@link java.util.concurrent.ConcurrentMap} with key case-insensitivity. See
   * {@link java.util.concurrent.ConcurrentMap}.
   *
   * @param <VALUE> type of values to be stored in the map
   * @return key case-insensitive concurrent map
   */
  public static <VALUE> CaseInsensitiveMap<VALUE> newConcurrentMap() {
    return new CaseInsensitiveMap<>(Maps.newConcurrentMap());
  }

  /**
   * Returns a new instance of {@link java.util.HashMap} with key case-insensitivity. See {@link java.util.HashMap}.
   *
   * @param <VALUE> type of values to be stored in the map
   * @return key case-insensitive hash map
   */
  public static <VALUE> CaseInsensitiveMap<VALUE> newHashMap() {
    return new CaseInsensitiveMap<>(Maps.newHashMap());
  }

  /**
   * Returns a new instance of {@link java.util.HashMap}, with key case-insensitivity, of expected size.
   * See {@link java.util.HashMap}.
   *
   * @param expectedSize expected size
   * @param <VALUE> type of values to be stored in the map
   * @return key case-insensitive hash map
   */
  public static <VALUE> CaseInsensitiveMap<VALUE> newHashMapWithExpectedSize(final int expectedSize) {
    return new CaseInsensitiveMap<>(Maps.newHashMapWithExpectedSize(expectedSize));
  }

  /**
   * Returns a new instance of {@link ImmutableMap} with key case-insensitivity. This map is built from the given
   * map. See {@link ImmutableMap}.
   *
   * @param map map to copy from
   * @param <VALUE> type of values to be stored in the map
   * @return key case-insensitive immutable map
   */
  public static <VALUE> CaseInsensitiveMap<VALUE> newImmutableMap(final Map<? extends String, ? extends VALUE> map) {
    final ImmutableMap.Builder<String, VALUE> builder = ImmutableMap.builder();
    for (final Entry<? extends String, ? extends VALUE> entry : map.entrySet()) {
      builder.put(entry.getKey().toLowerCase(), entry.getValue());
    }
    return new CaseInsensitiveMap<>(builder.build());
  }

  private final Map<String, VALUE> underlyingMap;

  /**
   * Use the static factory methods to create instances of this class (e.g. {@link #newConcurrentMap}).
   *
   * @param underlyingMap the underlying map
   */
  private CaseInsensitiveMap(final Map<String, VALUE> underlyingMap) {
    this.underlyingMap = underlyingMap;
  }

  @Override
  public int size() {
    return underlyingMap.size();
  }

  @Override
  public boolean isEmpty() {
    return underlyingMap.isEmpty();
  }

  @Override
  public boolean containsKey(final Object key) {
    return key instanceof String && underlyingMap.containsKey(((String) key).toLowerCase());
  }

  @Override
  public boolean containsValue(final Object value) {
    return underlyingMap.containsValue(value);
  }

  @Override
  public VALUE get(final Object key) {
    return key instanceof String ? underlyingMap.get(((String) key).toLowerCase()) : null;
  }

  @Override
  public VALUE put(final String key, final VALUE value) {
    return underlyingMap.put(key.toLowerCase(), value);
  }

  @Override
  public VALUE remove(final Object key) {
    return key instanceof String ? underlyingMap.remove(((String) key).toLowerCase()) : null;
  }

  @Override
  public void putAll(final Map<? extends String, ? extends VALUE> map) {
    for (final Entry<? extends String, ? extends VALUE> entry : map.entrySet()) {
      underlyingMap.put(entry.getKey().toLowerCase(), entry.getValue());
    }
  }

  @Override
  public void clear() {
    underlyingMap.clear();
  }

  @Override
  public Set<String> keySet() {
    return underlyingMap.keySet();
  }

  @Override
  public Collection<VALUE> values() {
    return underlyingMap.values();
  }

  @Override
  public Set<Entry<String, VALUE>> entrySet() {
    return underlyingMap.entrySet();
  }

  @Override
  public int hashCode() {
    return Objects.hash(underlyingMap);
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (!(o instanceof CaseInsensitiveMap)) {
      return false;
    }
    CaseInsensitiveMap<?> that = (CaseInsensitiveMap<?>) o;
    return Objects.equals(underlyingMap, that.underlyingMap);
  }

  @Override
  public String toString() {
    return underlyingMap.toString();
  }
}
