// Copyright 2023 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_RESOLVED_TARGET_DATA_H_
#define TOOLS_GN_RESOLVED_TARGET_DATA_H_

#include <atomic>
#include <memory>
#include <mutex>
#include <shared_mutex>
#include <vector>

#include "base/containers/span.h"
#include "gn/lib_file.h"
#include "gn/resolved_target_deps.h"
#include "gn/source_dir.h"
#include "gn/target.h"
#include "gn/target_public_pair.h"
#include "gn/unique_vector.h"

// A class used to compute target-specific data by collecting information
// from its tree of dependencies.
//
// For example, linkable targets can call GetLinkedLibraries() and
// GetLinkedLibraryDirs() to find the library files and library search
// paths to add to their final linker command string, based on the
// definitions of the `libs` and `lib_dirs` config values of their
// transitive dependencies.
//
// Values are computed on demand, but memorized by the class instance in order
// to speed up multiple queries for targets that share dependencies.
//
// Usage is:
//
//  1) Create instance.
//
//  2) Call any of the methods to retrieve the value of the corresponding
//     data. For all methods, the input Target instance passed as argument
//     must have been fully resolved (meaning that Target::OnResolved()
//     must have been called and completed). Input target pointers are
//     const and thus are never modified. This allows using multiple
//     ResolvedTargetData instances from the same input graph in multiple
//     threads safely.
//
class ResolvedTargetData {
 public:
  // Return the public/private/data/dependencies of a given target
  // as a ResolvedTargetDeps instance.
  const ResolvedTargetDeps& GetTargetDeps(const Target* target) const {
    return GetTargetInfo(target)->deps;
  }

  // Return the data dependencies of a given target.
  // Convenience shortcut for GetTargetDeps(target).data_deps().
  base::span<const Target*> GetDataDeps(const Target* target) const {
    return GetTargetDeps(target).data_deps();
  }

  // Return the public and private dependencies of a given target.
  // Convenience shortcut for GetTargetDeps(target).linked_deps().
  base::span<const Target*> GetLinkedDeps(const Target* target) const {
    return GetTargetDeps(target).linked_deps();
  }

  // The list of all library directory search path to add to the final link
  // command of linkable binary. For example, if this returns ['dir1', 'dir2']
  // a command for a C++ linker would typically use `-Ldir1 -Ldir2`.
  const std::vector<SourceDir>& GetLinkedLibraryDirs(
      const Target* target) const {
    return GetTargetLibInfo(target)->lib_dirs;
  }

  // The list of all library files to add to the final link command of linkable
  // binaries. For example, if this returns ['foo', '/path/to/bar'], the command
  // for a C++ linker would typically use '-lfoo /path/to/bar'.
  const std::vector<LibFile>& GetLinkedLibraries(const Target* target) const {
    return GetTargetLibInfo(target)->libs;
  }

  // The list of framework directories search paths to use at link time
  // when generating macOS or iOS linkable binaries.
  const std::vector<SourceDir>& GetLinkedFrameworkDirs(
      const Target* target) const {
    return GetTargetFrameworkInfo(target)->framework_dirs;
  }

  // The list of framework names to use at link time when generating macOS
  // or iOS linkable binaries.
  const std::vector<std::string>& GetLinkedFrameworks(
      const Target* target) const {
    return GetTargetFrameworkInfo(target)->frameworks;
  }

  // The list of weak framework names to use at link time when generating macOS
  // or iOS linkable binaries.
  const std::vector<std::string>& GetLinkedWeakFrameworks(
      const Target* target) const {
    return GetTargetFrameworkInfo(target)->weak_frameworks;
  }

  // The list of weak library files to use at link time when generating macOS
  // or iOS linkable binaries.
  const std::vector<std::string>& GetLinkedWeakLibraries(
      const Target* target) const {
    return GetTargetFrameworkInfo(target)->weak_libraries;
  }

  // Retrieves a set of hard dependencies for this target.
  // All hard deps from this target and all dependencies, but not the
  // target itself.
  const TargetSet& GetHardDeps(const Target* target) const {
    return GetTargetHardDeps(target)->hard_deps;
  }

  // Retrieves an ordered list of (target, is_public) pairs for all link-time
  // libraries inherited by this target.
  const std::vector<TargetPublicPair>& GetInheritedLibraries(
      const Target* target) const {
    return GetTargetInheritedLibs(target)->inherited_libs;
  }

  // Retrieves an ordered list of (target, is_public) pairs for all module
  // dependencies inherited by this target.
  const std::vector<TargetPublicPair>& GetModuleDepsInformation(
      const Target* target) const {
    return GetTargetModuleDepsInformation(target)->module_deps_information;
  }

  // Retrieves an ordered list of (target, is_public) paris for all link-time
  // libraries for Rust-specific binary targets.
  const std::vector<TargetPublicPair>& GetRustInheritedLibraries(
      const Target* target) const {
    return GetTargetRustLibs(target)->rust_inherited_libs;
  }

  // List of dependent target that generate a .swiftmodule. The current target
  // is assumed to depend on those modules, and will add them to the module
  // search path.
  base::span<const Target*> GetSwiftModuleDependencies(
      const Target* target) const {
    const TargetInfo* info = GetTargetSwiftValues(target);
    if (!info->swift_values.get())
      return {};
    return info->swift_values->modules;
  }

 private:
  // The information associated with a given Target pointer.
  struct TargetInfo {
    TargetInfo() = default;

    TargetInfo(const Target* target)
        : target(target),
          deps(target->public_deps(),
               target->private_deps(),
               target->data_deps()) {}

    const Target* target = nullptr;
    ResolvedTargetDeps deps;
    mutable std::mutex mutex;

    std::atomic<bool> has_lib_info = false;
    std::atomic<bool> has_framework_info = false;
    std::atomic<bool> has_hard_deps = false;
    std::atomic<bool> has_inherited_libs = false;
    std::atomic<bool> has_module_deps_information = false;
    std::atomic<bool> has_rust_libs = false;
    std::atomic<bool> has_swift_values = false;

    // Only valid if |has_lib_info| is true.
    std::vector<SourceDir> lib_dirs;
    std::vector<LibFile> libs;

    // Only valid if |has_framework_info| is true.
    std::vector<SourceDir> framework_dirs;
    std::vector<std::string> frameworks;
    std::vector<std::string> weak_frameworks;
    std::vector<std::string> weak_libraries;

    // Only valid if |has_hard_deps| is true.
    TargetSet hard_deps;

    // Only valid if |has_inherited_libs| is true.
    std::vector<TargetPublicPair> inherited_libs;

    // Only valid if |has_module_deps_information| is true.
    std::vector<TargetPublicPair> module_deps_information;

    // Only valid if |has_rust_libs| is true.
    std::vector<TargetPublicPair> rust_inherited_libs;
    std::vector<TargetPublicPair> rust_inheritable_libs;

    // Only valid if |has_swift_values| is true.
    // Most targets will not have Swift dependencies, so only
    // allocate a SwiftValues struct when needed. A null pointer
    // indicates empty lists.
    struct SwiftValues {
      std::vector<const Target*> modules;
      std::vector<const Target*> public_modules;

      SwiftValues(std::vector<const Target*> modules,
                  std::vector<const Target*> public_modules)
          : modules(std::move(modules)),
            public_modules(std::move(public_modules)) {}
    };
    std::unique_ptr<SwiftValues> swift_values;
  };

  // Retrieve TargetInfo value associated with |target|. Create
  // a new empty instance on demand if none is already available.
  TargetInfo* GetTargetInfo(const Target* target) const;

  const TargetInfo* GetTargetLibInfo(const Target* target) const {
    TargetInfo* info = GetTargetInfo(target);
    if (!info->has_lib_info.load(std::memory_order_acquire)) {
      std::lock_guard<std::mutex> lock(info->mutex);
      if (!info->has_lib_info.load(std::memory_order_relaxed)) {
        ComputeLibInfo(info);
        info->has_lib_info.store(true, std::memory_order_release);
      }
    }
    return info;
  }

  const TargetInfo* GetTargetFrameworkInfo(const Target* target) const {
    TargetInfo* info = GetTargetInfo(target);
    if (!info->has_framework_info.load(std::memory_order_acquire)) {
      std::lock_guard<std::mutex> lock(info->mutex);
      if (!info->has_framework_info.load(std::memory_order_relaxed)) {
        ComputeFrameworkInfo(info);
        info->has_framework_info.store(true, std::memory_order_release);
      }
    }
    return info;
  }

  const TargetInfo* GetTargetHardDeps(const Target* target) const {
    TargetInfo* info = GetTargetInfo(target);
    if (!info->has_hard_deps.load(std::memory_order_acquire)) {
      std::lock_guard<std::mutex> lock(info->mutex);
      if (!info->has_hard_deps.load(std::memory_order_relaxed)) {
        ComputeHardDeps(info);
        info->has_hard_deps.store(true, std::memory_order_release);
      }
    }
    return info;
  }

  const TargetInfo* GetTargetInheritedLibs(const Target* target) const {
    TargetInfo* info = GetTargetInfo(target);
    if (!info->has_inherited_libs.load(std::memory_order_acquire)) {
      std::lock_guard<std::mutex> lock(info->mutex);
      if (!info->has_inherited_libs.load(std::memory_order_relaxed)) {
        ComputeInheritedLibs(info);
        info->has_inherited_libs.store(true, std::memory_order_release);
      }
    }
    return info;
  }

  const TargetInfo* GetTargetModuleDepsInformation(const Target* target) const {
    TargetInfo* info = GetTargetInfo(target);
    if (!info->has_module_deps_information.load(std::memory_order_acquire)) {
      std::lock_guard<std::mutex> lock(info->mutex);
      if (!info->has_module_deps_information.load(std::memory_order_relaxed)) {
        ComputeModuleDepsInformation(info);
        info->has_module_deps_information.store(true,
                                                std::memory_order_release);
      }
    }
    return info;
  }

  const TargetInfo* GetTargetRustLibs(const Target* target) const {
    TargetInfo* info = GetTargetInfo(target);
    if (!info->has_rust_libs.load(std::memory_order_acquire)) {
      std::lock_guard<std::mutex> lock(info->mutex);
      if (!info->has_rust_libs.load(std::memory_order_relaxed)) {
        ComputeRustLibs(info);
        info->has_rust_libs.store(true, std::memory_order_release);
      }
    }
    return info;
  }

  const TargetInfo* GetTargetSwiftValues(const Target* target) const {
    TargetInfo* info = GetTargetInfo(target);
    if (!info->has_swift_values.load(std::memory_order_acquire)) {
      std::lock_guard<std::mutex> lock(info->mutex);
      if (!info->has_swift_values.load(std::memory_order_relaxed)) {
        ComputeSwiftValues(info);
        info->has_swift_values.store(true, std::memory_order_release);
      }
    }
    return info;
  }

  // Compute the portion of TargetInfo guarded by one of the |has_xxx|
  // booleans. This performs recursive and expensive computations and
  // should only be called once per TargetInfo instance.
  void ComputeLibInfo(TargetInfo* info) const;
  void ComputeFrameworkInfo(TargetInfo* info) const;
  void ComputeHardDeps(TargetInfo* info) const;
  void ComputeInheritedLibs(TargetInfo* info) const;
  void ComputeModuleDepsInformation(TargetInfo* info) const;
  void ComputeRustLibs(TargetInfo* info) const;
  void ComputeSwiftValues(TargetInfo* info) const;

  // Helper function used by ComputeInheritedLibs().
  void ComputeInheritedLibsFor(
      base::span<const Target*> deps,
      bool is_public,
      TargetPublicPairListBuilder* inherited_libraries) const;

  // Helper function used by ComputeModuleDepsInformation().
  void ComputeModuleDepsInformationFor(
      base::span<const Target*> deps,
      bool is_public,
      TargetPublicPairListBuilder* module_deps_information) const;

  // Helper data structure and function used by ComputeRustLibs().
  struct RustLibsBuilder {
    TargetPublicPairListBuilder inherited;
    TargetPublicPairListBuilder inheritable;
  };

  void ComputeRustLibsFor(base::span<const Target*> deps,
                          bool is_public,
                          RustLibsBuilder* rust_libs) const;

  // A { Target* -> TargetInfo } map that will create entries
  // on demand (hence the mutable qualifier). Implemented with a
  // UniqueVector<> and a parallel vector of unique TargetInfo
  // instances for best performance.
  mutable std::shared_mutex map_mutex_;
  mutable UniqueVector<const Target*> targets_;
  mutable std::vector<std::unique_ptr<TargetInfo>> infos_;
};

#endif  // TOOLS_GN_RESOLVED_TARGET_DATA_H_
