// Copyright (c) 2013 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 TOOLS_GN_BUILDER_RECORD_H_
#define TOOLS_GN_BUILDER_RECORD_H_

#include <set>

#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "tools/gn/item.h"
#include "tools/gn/location.h"

class ParseNode;

// This class is used by the builder to manage the loading of the dependency
// tree. It holds a reference to an item and links to other records that the
// item depends on, both resolved ones, and unresolved ones.
//
// If a target depends on another one that hasn't been defined yet, we'll make
// a placeholder BuilderRecord with no item, and try to load the buildfile
// associated with the new item. The item will get filled in when we encounter
// the declaration for the item (or when we're done and realize there are
// undefined items).
//
// You can also have null item pointers when the target is not required for
// the current build (should_generate is false).
class BuilderRecord {
 public:
  typedef std::set<BuilderRecord*> BuilderRecordSet;

  enum ItemType {
    ITEM_UNKNOWN,
    ITEM_TARGET,
    ITEM_CONFIG,
    ITEM_TOOLCHAIN
  };

  BuilderRecord(ItemType type, const Label& label);
  ~BuilderRecord();

  ItemType type() const { return type_; }
  const Label& label() const { return label_; }

  // Returns a user-ready name for the given type. e.g. "target".
  static const char* GetNameForType(ItemType type);

  // Returns true if the given item is of the given type.
  static bool IsItemOfType(const Item* item, ItemType type);

  // Returns the type enum for the given item.
  static ItemType TypeOfItem(const Item* item);

  Item* item() { return item_.get(); }
  const Item* item() const { return item_.get(); }
  void set_item(scoped_ptr<Item> item) { item_ = item.Pass(); }

  // Indicates from where this item was originally referenced from that caused
  // it to be loaded. For targets for which we encountered the declaration
  // before a reference, this will be the empty range.
  const ParseNode* originally_referenced_from() const {
    return originally_referenced_from_;
  }
  void set_originally_referenced_from(const ParseNode* pn) {
    originally_referenced_from_ = pn;
  }

  bool should_generate() const { return should_generate_; }
  void set_should_generate(bool sg) { should_generate_ = sg; }

  bool resolved() const { return resolved_; }
  void set_resolved(bool r) { resolved_ = r; }

  bool can_resolve() const {
    return item_ && unresolved_deps_.empty();
  }

  // All records this one is depending on.
  BuilderRecordSet& all_deps() { return all_deps_; }
  const BuilderRecordSet& all_deps() const { return all_deps_; }

  // Unresolved records this one is depending on. A subset of all... above.
  BuilderRecordSet& unresolved_deps() { return unresolved_deps_; }
  const BuilderRecordSet& unresolved_deps() const { return unresolved_deps_; }

  // Records that are waiting on this one to be resolved. This is the other
  // end of the "unresolved deps" arrow.
  BuilderRecordSet& waiting_on_resolution() { return waiting_on_resolution_; }
  const BuilderRecordSet& waiting_on_resolution() const {
    return waiting_on_resolution_;
  }

  void AddDep(BuilderRecord* record);

 private:
  ItemType type_;
  Label label_;
  scoped_ptr<Item> item_;
  const ParseNode* originally_referenced_from_;
  bool should_generate_;
  bool resolved_;

  BuilderRecordSet all_deps_;
  BuilderRecordSet unresolved_deps_;
  BuilderRecordSet waiting_on_resolution_;

  DISALLOW_COPY_AND_ASSIGN(BuilderRecord);
};

#endif  // TOOLS_GN_BUILDER_RECORD_H_
