// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef Iterable_h
#define Iterable_h

#include "bindings/core/v8/V8IteratorResultValue.h"
#include "bindings/core/v8/V8ScriptRunner.h"
#include "core/dom/Iterator.h"

namespace blink {

// Typically, you should use PairIterable<> (below) instead.
// Also, note that value iterators are set up automatically by the bindings
// code and the operations below come directly from V8.
template <typename KeyType, typename ValueType>
class Iterable {
 public:
  Iterator* keysForBinding(ScriptState* scriptState,
                           ExceptionState& exceptionState) {
    IterationSource* source = this->startIteration(scriptState, exceptionState);
    if (!source)
      return nullptr;
    return new IterableIterator<KeySelector>(source);
  }

  Iterator* valuesForBinding(ScriptState* scriptState,
                             ExceptionState& exceptionState) {
    IterationSource* source = this->startIteration(scriptState, exceptionState);
    if (!source)
      return nullptr;
    return new IterableIterator<ValueSelector>(source);
  }

  Iterator* entriesForBinding(ScriptState* scriptState,
                              ExceptionState& exceptionState) {
    IterationSource* source = this->startIteration(scriptState, exceptionState);
    if (!source)
      return nullptr;
    return new IterableIterator<EntrySelector>(source);
  }

  void forEachForBinding(ScriptState* scriptState,
                         const ScriptValue& thisValue,
                         const ScriptValue& callback,
                         const ScriptValue& thisArg,
                         ExceptionState& exceptionState) {
    IterationSource* source = this->startIteration(scriptState, exceptionState);

    v8::Isolate* isolate = scriptState->isolate();
    v8::TryCatch tryCatch(isolate);

    v8::Local<v8::Object> creationContext(thisValue.v8Value().As<v8::Object>());
    v8::Local<v8::Function> v8Callback(callback.v8Value().As<v8::Function>());
    v8::Local<v8::Value> v8ThisArg(thisArg.v8Value());
    v8::Local<v8::Value> args[3];

    args[2] = thisValue.v8Value();

    while (true) {
      KeyType key;
      ValueType value;

      if (!source->next(scriptState, key, value, exceptionState))
        return;

      ASSERT(!exceptionState.hadException());

      args[0] = ToV8(value, creationContext, isolate);
      args[1] = ToV8(key, creationContext, isolate);
      if (args[0].IsEmpty() || args[1].IsEmpty()) {
        if (tryCatch.HasCaught())
          exceptionState.rethrowV8Exception(tryCatch.Exception());
        return;
      }

      v8::Local<v8::Value> result;
      if (!V8ScriptRunner::callFunction(v8Callback,
                                        scriptState->getExecutionContext(),
                                        v8ThisArg, 3, args, isolate)
               .ToLocal(&result)) {
        exceptionState.rethrowV8Exception(tryCatch.Exception());
        return;
      }
    }
  }

  class IterationSource : public GarbageCollectedFinalized<IterationSource> {
   public:
    virtual ~IterationSource() {}

    // If end of iteration has been reached or an exception thrown: return
    // false.  Otherwise: set |key| and |value| and return true.
    virtual bool next(ScriptState*, KeyType&, ValueType&, ExceptionState&) = 0;

    DEFINE_INLINE_VIRTUAL_TRACE() {}
  };

 private:
  virtual IterationSource* startIteration(ScriptState*, ExceptionState&) = 0;

  struct KeySelector {
    STATIC_ONLY(KeySelector);
    static const KeyType& select(ScriptState*,
                                 const KeyType& key,
                                 const ValueType& value) {
      return key;
    }
  };
  struct ValueSelector {
    STATIC_ONLY(ValueSelector);
    static const ValueType& select(ScriptState*,
                                   const KeyType& key,
                                   const ValueType& value) {
      return value;
    }
  };
  struct EntrySelector {
    STATIC_ONLY(EntrySelector);
    static Vector<ScriptValue, 2> select(ScriptState* scriptState,
                                         const KeyType& key,
                                         const ValueType& value) {
      v8::Local<v8::Object> creationContext = scriptState->context()->Global();
      v8::Isolate* isolate = scriptState->isolate();

      Vector<ScriptValue, 2> entry;
      entry.push_back(
          ScriptValue(scriptState, ToV8(key, creationContext, isolate)));
      entry.push_back(
          ScriptValue(scriptState, ToV8(value, creationContext, isolate)));
      return entry;
    }
  };

  template <typename Selector>
  class IterableIterator final : public Iterator {
   public:
    explicit IterableIterator(IterationSource* source) : m_source(source) {}

    ScriptValue next(ScriptState* scriptState,
                     ExceptionState& exceptionState) override {
      KeyType key;
      ValueType value;

      if (!m_source->next(scriptState, key, value, exceptionState))
        return v8IteratorResultDone(scriptState);

      return v8IteratorResult(scriptState,
                              Selector::select(scriptState, key, value));
    }

    ScriptValue next(ScriptState* scriptState,
                     ScriptValue,
                     ExceptionState& exceptionState) override {
      return next(scriptState, exceptionState);
    }

    DEFINE_INLINE_VIRTUAL_TRACE() {
      visitor->trace(m_source);
      Iterator::trace(visitor);
    }

   private:
    Member<IterationSource> m_source;
  };
};

// Utiltity mixin base-class for classes implementing IDL interfaces with
// "iterable<T1, T2>".
template <typename KeyType, typename ValueType>
class PairIterable : public Iterable<KeyType, ValueType> {
 public:
  Iterator* iterator(ScriptState* scriptState, ExceptionState& exceptionState) {
    return this->entriesForBinding(scriptState, exceptionState);
  }
};

}  // namespace blink

#endif  // Iterable_h
