/*
 * Copyright 2014 Google Inc.
 *
 * 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 java.util;

import static java.util.ConcurrentModificationDetector.structureChanged;

import java.util.Map.Entry;

import javaemul.internal.JsUtils;

/**
 * A simple wrapper around JavaScript Map for key type is string.
 */
class InternalStringMap<K, V> implements Iterable<Entry<K, V>> {

  private final InternalJsMap<V> backingMap = InternalJsMapFactory.newJsMap();
  private AbstractHashMap<K, V> host;
  private int size;

  /**
   * A mod count to track 'value' replacements in map to ensure that the 'value' that we have in the
   * iterator entry is guaranteed to be still correct.
   * This is to optimize for the common scenario where the values are not modified during
   * iterations where the entries are never stale.
   */
  private int valueMod;

  public InternalStringMap(AbstractHashMap<K, V> host) {
    this.host = host;
  }

  public boolean contains(String key) {
    return !JsUtils.isUndefined(backingMap.get(key));
  }

  public V get(String key) {
    return backingMap.get(key);
  }

  public V put(String key, V value) {
    V oldValue = backingMap.get(key);
    backingMap.set(key, toNullIfUndefined(value));

    if (JsUtils.isUndefined(oldValue)) {
      size++;
      structureChanged(host);
    } else {
      valueMod++;
    }
    return oldValue;
  }

  public V remove(String key) {
    V value = backingMap.get(key);
    if (!JsUtils.isUndefined(value)) {
      backingMap.delete(key);
      size--;
      structureChanged(host);
    } else {
      valueMod++;
    }

    return value;
  }

  public int size() {
    return size;
  }

  @Override
  public Iterator<Entry<K, V>> iterator() {
    return new Iterator<Map.Entry<K, V>>() {
      InternalJsMap.Iterator<V> entries = backingMap.entries();
      InternalJsMap.IteratorEntry<V> current = entries.next();
      InternalJsMap.IteratorEntry<V> last;

      @Override
      public boolean hasNext() {
        return !current.isDone();
      }

      @Override
      public Entry<K, V> next() {
        last = current;
        current = entries.next();
        return newMapEntry(last, valueMod);
      }

      @Override
      public void remove() {
        InternalStringMap.this.remove(last.getKey());
      }
    };
  }

  private Entry<K, V> newMapEntry(
      final InternalJsMap.IteratorEntry<V> entry, final int lastValueMod) {
    return new AbstractMapEntry<K, V>() {
      @SuppressWarnings("unchecked")
      @Override
      public K getKey() {
        return (K) entry.getKey();
      }

      @Override
      public V getValue() {
        if (valueMod != lastValueMod) {
          // Let's get a fresh copy as the value may have changed.
          return get(entry.getKey());
        }
        return entry.getValue();
      }

      @Override
      public V setValue(V object) {
        return put(entry.getKey(), object);
      }
    };
  }

  private static <T> T toNullIfUndefined(T value) {
    return JsUtils.isUndefined(value) ? null : value;
  }
}
