/*
 * 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_SRC_DEX_METHOD_ITERATOR_H_
#define ART_SRC_DEX_METHOD_ITERATOR_H_

#include <vector>

#include "dex_file.h"

namespace art {

class DexMethodIterator {
 public:
  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_(NULL),
        class_data_(NULL),
        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_ == NULL) {
        class_def_ = &GetDexFileInternal().GetClassDef(class_def_index_);
      }
      if (class_data_ == NULL) {
        class_data_ = GetDexFileInternal().GetClassData(*class_def_);
        if (class_data_ == NULL) {
          // empty class, such as a marker interface
          // End of this class, advance and retry.
          class_def_ = NULL;
          class_def_index_++;
          continue;
        }
      }
      if (it_.get() == NULL) {
        it_.reset(new ClassDataItemIterator(GetDexFileInternal(), class_data_));
        // Skip fields
        while (GetIterator().HasNextStaticField()) {
          GetIterator().Next();
        }
        while (GetIterator().HasNextInstanceField()) {
          GetIterator().Next();
        }
        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(NULL);
      class_data_ = NULL;
      class_def_ = NULL;
      class_def_index_++;
    }
  }

  void Next() {
    found_next_ = false;
    if (it_.get() != NULL) {
      // 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_ != NULL);
    return GetIterator().GetMethodInvokeType(*class_def_);
  }

 private:

  ClassDataItemIterator& GetIterator() const {
    CHECK(it_.get() != NULL);
    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 != NULL);
    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 byte* class_data_;
  UniquePtr<ClassDataItemIterator> it_;
  bool direct_method_;
};

}  // namespace art

#endif  // ART_SRC_DEX_METHOD_ITERATOR_H_
