/*
 * 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.flink.table.api.dataview

import java.lang.{Iterable => JIterable}
import java.util

import org.apache.flink.api.common.typeinfo.TypeInfo
import org.apache.flink.table.api.functions.AggregateFunction
import org.apache.flink.table.api.types.DataType
import org.apache.flink.table.typeutils.MapViewTypeInfoFactory

/**
  * A [[MapView]] provides Map functionality for accumulators used by user-defined aggregate
  * functions [[AggregateFunction]].
  *
  * A [[MapView]] can be backed by a Java HashMap or a state backend, depending on the context in
  * which the aggregation function is used.
  *
  * At runtime [[MapView]] will be replaced by a
  * [[org.apache.flink.table.dataview.KeyedStateMapView]] if it is backed by a state backend.
  *
  * Example of an accumulator type with a [[MapView]] and an aggregate function that uses it:
  * {{{
  *
  *  public class MyAccum {
  *    public MapView<String, Integer> map;
  *    public long count;
  *  }
  *
  *  public class MyAgg extends AggregateFunction<Long, MyAccum> {
  *
  *    @Override
  *    public MyAccum createAccumulator() {
  *      MyAccum accum = new MyAccum();
  *      accum.map = new MapView<>(Types.STRING, Types.INT);
  *      accum.count = 0L;
  *      return accum;
  *    }
  *
  *    public void accumulate(MyAccum accumulator, String id) {
  *      try {
  *          if (!accumulator.map.contains(id)) {
  *            accumulator.map.put(id, 1);
  *            accumulator.count++;
  *          }
  *      } catch (Exception e) {
  *        e.printStackTrace();
  *      }
  *    }
  *
  *    @Override
  *    public Long getValue(MyAccum accumulator) {
  *      return accumulator.count;
  *    }
  *  }
  *
  * }}}
  *
  * @param keyType key type
  * @param valueType value type
  * @tparam K key type
  * @tparam V value type
  */
@TypeInfo(classOf[MapViewTypeInfoFactory[_, _]])
class MapView[K, V](
    @transient private[flink] val keyType: DataType,
    @transient private[flink] val valueType: DataType,
    private[flink] val map: util.Map[K, V])
  extends DataView {

  /**
    * Creates a MapView with the specified key and value types.
    *
    * @param keyType The type of keys of the MapView.
    * @param valueType The type of the values of the MapView.
    */
  def this(keyType: DataType, valueType: DataType) {
    this(keyType, valueType, new util.HashMap[K, V]())
  }

  /**
    * Creates a MapView.
    */
  def this() = this(null, null)

  /**
    * Return the value for the specified key or { @code null } if the key is not in the map view.
    *
    * @param key The look up key.
    * @return The value for the specified key.
    * @throws Exception Thrown if the system cannot get data.
    */
  @throws[Exception]
  def get(key: K): V = map.get(key)

  /**
    * Inserts a value for the given key into the map view.
    * If the map view already contains a value for the key, the existing value is overwritten.
    *
    * @param key   The key for which the value is inserted.
    * @param value The value that is inserted for the key.
    * @throws Exception Thrown if the system cannot put data.
    */
  @throws[Exception]
  def put(key: K, value: V): Unit = map.put(key, value)

  /**
    * Inserts all mappings from the specified map to this map view.
    *
    * @param map The map whose entries are inserted into this map view.
    * @throws Exception Thrown if the system cannot access the map.
    */
  @throws[Exception]
  def putAll(map: util.Map[K, V]): Unit = this.map.putAll(map)

  /**
    * Deletes the value for the given key.
    *
    * @param key The key for which the value is deleted.
    * @throws Exception Thrown if the system cannot access the map.
    */
  @throws[Exception]
  def remove(key: K): Unit = map.remove(key)

  /**
    * Checks if the map view contains a value for a given key.
    *
    * @param key The key to check.
    * @return True if there exists a value for the given key, false otherwise.
    * @throws Exception Thrown if the system cannot access the map.
    */
  @throws[Exception]
  def contains(key: K): Boolean = map.containsKey(key)

  /**
    * Returns all entries of the map view.
    *
    * @return An iterable of all the key-value pairs in the map view.
    * @throws Exception Thrown if the system cannot access the map.
    */
  @throws[Exception]
  def entries: JIterable[util.Map.Entry[K, V]] = map.entrySet()

  /**
    * Returns all the keys in the map view.
    *
    * @return An iterable of all the keys in the map.
    * @throws Exception Thrown if the system cannot access the map.
    */
  @throws[Exception]
  def keys: JIterable[K] = map.keySet()

  /**
    * Returns all the values in the map view.
    *
    * @return An iterable of all the values in the map.
    * @throws Exception Thrown if the system cannot access the map.
    */
  @throws[Exception]
  def values: JIterable[V] = map.values()

  /**
    * Returns an iterator over all entries of the map view.
    *
    * @return An iterator over all the mappings in the map.
    * @throws Exception Thrown if the system cannot access the map.
    */
  @throws[Exception]
  def iterator: util.Iterator[util.Map.Entry[K, V]] = map.entrySet().iterator()

  /**
    * Removes all entries of this map.
    */
  override def clear(): Unit = map.clear()

  override def equals(other: Any): Boolean = other match {
    case that: MapView[K, V] =>
        map.equals(that.map)
    case _ => false
  }

  override def hashCode(): Int = map.hashCode()
}
