// Copyright 2020 The Fuchsia 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_FIDL_FIDLC_INCLUDE_FIDL_FLAT_NAME_H_
#define TOOLS_FIDL_FIDLC_INCLUDE_FIDL_FLAT_NAME_H_

#include <optional>
#include <string>
#include <string_view>
#include <variant>

#include "fidl/source_span.h"

namespace fidl {
namespace flat {

class Library;

// Name represents a named entry in a particular scope.

// Names have different flavors based on their origins, which can be determined by the discriminant
// `Name::Kind`. See the documentation for `Name::Kind` for details.
class Name final {
 public:
  // Helper type to use when looking up and comparing names. This may be useful for associative
  // containers.
  //
  // Note that this type contains `std::string_view`s, so it must not outlive the strings its
  // members reference.
  class Key final {
   public:
    // Intentionally allow for implicit conversions from `Name`, as `Name` should be freely
    // convertible to its `Key`.
    //
    // NOLINTNEXTLINE
    Key(const Name& name)
        : compare_context_(name.library(), name.decl_name(),
                           name.member_name().has_value()
                               ? std::make_optional(std::string_view(name.member_name().value()))
                               : std::nullopt) {}

    explicit Key(const Library* library, std::string_view decl_name)
        : compare_context_(library, decl_name, std::nullopt) {}

    explicit Key(const Library* library, std::string_view decl_name, std::string_view member_name)
        : compare_context_(library, decl_name, member_name) {}

    friend bool operator==(const Key& lhs, const Key& rhs) {
      return lhs.compare_context_ == rhs.compare_context_;
    }

    friend bool operator!=(const Key& lhs, const Key& rhs) {
      return lhs.compare_context_ != rhs.compare_context_;
    }

    friend bool operator<(const Key& lhs, const Key& rhs) {
      return lhs.compare_context_ < rhs.compare_context_;
    }

   private:
    using CompareContext =
        std::tuple<const Library*, std::string_view, std::optional<std::string_view>>;

    CompareContext compare_context_;
  };

  static Name CreateSourced(const Library* library, SourceSpan span) {
    return Name(library, SourcedNameContext(span), std::nullopt);
  }

  static Name CreateSourced(const Library* library, SourceSpan span, std::string member_name) {
    return Name(library, SourcedNameContext(span), member_name);
  }

  static Name CreateDerived(const Library* library, SourceSpan span, std::string name) {
    return Name(library, DerivedNameContext(std::move(name), span), std::nullopt);
  }

  static Name CreateIntrinsic(std::string name) {
    return Name(nullptr, IntrinsicNameContext(std::move(name)), std::nullopt);
  }

  Name(const Name& other) noexcept
      : library_(other.library_),
        name_context_(other.name_context_),
        member_name_(other.member_name_) {}

  Name(Name&& other) noexcept
      : library_(other.library_),
        name_context_(std::move(other.name_context_)),
        member_name_(std::move(other.member_name_)) {
    other.library_ = nullptr;
    other.name_context_ = std::monostate();
  }

  Name& operator=(const Name& other) noexcept {
    if (&other == this) {
      return *this;
    }

    library_ = other.library_;
    name_context_ = other.name_context_;

    return *this;
  }

  Name& operator=(Name&& other) noexcept {
    if (&other == this) {
      return *this;
    }

    library_ = other.library_;
    other.library_ = nullptr;
    name_context_ = std::move(other.name_context_);
    other.name_context_ = std::monostate();

    return *this;
  }

  const Library* library() const { return library_; }

  std::optional<SourceSpan> span() const {
    return std::visit(
        [](auto&& name_context) -> std::optional<SourceSpan> {
          using T = std::decay_t<decltype(name_context)>;
          if constexpr (std::is_same_v<T, SourcedNameContext>) {
            return std::optional(name_context.span);
          } else if constexpr (std::is_same_v<T, DerivedNameContext>) {
            return std::optional(name_context.span);
          } else if constexpr (std::is_same_v<T, IntrinsicNameContext>) {
            return std::nullopt;
          } else {
            abort();
          }
        },
        name_context_);
  }

  std::string_view decl_name() const {
    return std::visit(
        [](auto&& name_context) -> std::string_view {
          using T = std::decay_t<decltype(name_context)>;
          if constexpr (std::is_same_v<T, SourcedNameContext>) {
            return name_context.span.data();
          } else if constexpr (std::is_same_v<T, DerivedNameContext>) {
            return std::string_view(name_context.name);
          } else if constexpr (std::is_same_v<T, IntrinsicNameContext>) {
            return std::string_view(name_context.name);
          } else {
            abort();
          }
        },
        name_context_);
  }

  std::string full_name() const {
    auto name = std::string(decl_name());
    if (member_name_.has_value()) {
      constexpr std::string_view kSeparator = ".";
      name.reserve(name.size() + kSeparator.size() + member_name_.value().size());

      name.append(kSeparator);
      name.append(member_name_.value());
    }
    return name;
  }

  const std::optional<std::string>& member_name() const { return member_name_; }

  Key memberless_key() const { return Key(library_, decl_name()); }

  Key key() const { return Key(*this); }

  friend bool operator==(const Name& lhs, const Name& rhs) { return lhs.key() == rhs.key(); }

  friend bool operator!=(const Name& lhs, const Name& rhs) { return lhs.key() != rhs.key(); }

  friend bool operator<(const Name& lhs, const Name& rhs) { return lhs.key() < rhs.key(); }

 private:
  struct SourcedNameContext {
    explicit SourcedNameContext(SourceSpan span) : span(span) {}

    // The span of the name.
    SourceSpan span;
  };

  struct DerivedNameContext {
    explicit DerivedNameContext(std::string name, SourceSpan span)
        : name(std::move(name)), span(span) {}

    // The derived name.
    std::string name;

    // The span from which the name was derived.
    SourceSpan span;
  };

  struct IntrinsicNameContext {
    explicit IntrinsicNameContext(std::string name) : name(std::move(name)) {}

    // The intrinsic name.
    std::string name;
  };

  Name(const Library* library, SourcedNameContext name_context,
       std::optional<std::string> member_name)
      : library_(library),
        name_context_(std::move(name_context)),
        member_name_(std::move(member_name)) {}

  Name(const Library* library, DerivedNameContext name_context,
       std::optional<std::string> member_name)
      : library_(library),
        name_context_(std::move(name_context)),
        member_name_(std::move(member_name)) {}

  Name(const Library* library, IntrinsicNameContext name_context,
       std::optional<std::string> member_name)
      : library_(library),
        name_context_(std::move(name_context)),
        member_name_(std::move(member_name)) {}

  const Library* library_;
  std::variant<std::monostate, SourcedNameContext, DerivedNameContext, IntrinsicNameContext>
      name_context_;
  std::optional<std::string> member_name_;
};

}  // namespace flat
}  // namespace fidl

#endif  // TOOLS_FIDL_FIDLC_INCLUDE_FIDL_FLAT_NAME_H_
