/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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.
 */

#ifndef ART_RUNTIME_DEX_METHOD_ITERATOR_H_
#define ART_RUNTIME_DEX_METHOD_ITERATOR_H_

#include <vector>

#include "dex_file.h"

namespace art {

class DexMethodIterator {
 public:
  explicit DexMethodIterator(const std::vector<const DexFile*>& dex_files)
      : dex_files_(dex_files),
        found_next_(false),
        dex_file_index_(0),
        class_def_index_(0),
        class_def_(nullptr),
        class_data_(nullptr),
        direct_method_(false) {
    CHECK_NE(0U, dex_files_.size());
  }

  bool HasNext() {
    if (found_next_) {
      return true;
    }
    while (true) {
      // End of DexFiles, we are done.
      if (dex_file_index_ == dex_files_.size()) {
        return false;
      }
      if (class_def_index_ == GetDexFileInternal().NumClassDefs()) {
        // End of this DexFile, advance and retry.
        class_def_index_ = 0;
        dex_file_index_++;
        continue;
      }
      if (class_def_ == nullptr) {
        class_def_ = &GetDexFileInternal().GetClassDef(class_def_index_);
      }
      if (class_data_ == nullptr) {
        class_data_ = GetDexFileInternal().GetClassData(*class_def_);
        if (class_data_ == nullptr) {
          // empty class, such as a marker interface
          // End of this class, advance and retry.
          class_def_ = nullptr;
          class_def_index_++;
          continue;
        }
      }
      if (it_.get() == nullptr) {
        it_.reset(new ClassDataItemIterator(GetDexFileInternal(), class_data_));
        GetIterator().SkipAllFields();
        direct_method_ = true;
      }
      if (direct_method_ && GetIterator().HasNextDirectMethod()) {
        // Found method
        found_next_ = true;
        return true;
      }
      direct_method_ = false;
      if (GetIterator().HasNextVirtualMethod()) {
        // Found method
        found_next_ = true;
        return true;
      }
      // End of this class, advance and retry.
      DCHECK(!GetIterator().HasNext());
      it_.reset(nullptr);
      class_data_ = nullptr;
      class_def_ = nullptr;
      class_def_index_++;
    }
  }

  void Next() {
    found_next_ = false;
    if (it_.get() != nullptr) {
      // Advance to next method if we currently are looking at a class.
      GetIterator().Next();
    }
  }

  const DexFile& GetDexFile() {
    CHECK(HasNext());
    return GetDexFileInternal();
  }

  uint32_t GetMemberIndex() {
    CHECK(HasNext());
    return GetIterator().GetMemberIndex();
  }

  InvokeType GetInvokeType() {
    CHECK(HasNext());
    CHECK(class_def_ != nullptr);
    return GetIterator().GetMethodInvokeType(*class_def_);
  }

 private:
  ClassDataItemIterator& GetIterator() const {
    CHECK(it_.get() != nullptr);
    return *it_.get();
  }

  const DexFile& GetDexFileInternal() const {
    CHECK_LT(dex_file_index_, dex_files_.size());
    const DexFile* dex_file = dex_files_[dex_file_index_];
    CHECK(dex_file != nullptr);
    return *dex_file;
  }

  const std::vector<const DexFile*>& dex_files_;

  bool found_next_;

  uint32_t dex_file_index_;
  uint32_t class_def_index_;
  const DexFile::ClassDef* class_def_;
  const uint8_t* class_data_;
  std::unique_ptr<ClassDataItemIterator> it_;
  bool direct_method_;
};

}  // namespace art

#endif  // ART_RUNTIME_DEX_METHOD_ITERATOR_H_
