// Copyright 2017 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 NET_TRAFFIC_ANNOTATION_NETWORK_TRAFFIC_ANNOTATION_H_
#define NET_TRAFFIC_ANNOTATION_NETWORK_TRAFFIC_ANNOTATION_H_

#include "base/logging.h"
#include "build/build_config.h"

namespace {

// Recursively compute hash code of the given string as a constant expression.
template <int N>
constexpr uint32_t recursive_hash(const char* str) {
  return static_cast<uint32_t>((recursive_hash<N - 1>(str) * 31 + str[N - 1]) %
                               138003713);
}

// Recursion stopper for the above function. Note that string of size 0 will
// result in compile error.
template <>
constexpr uint32_t recursive_hash<1>(const char* str) {
  return static_cast<uint32_t>(*str);
}

// Entry point to function that computes hash as constant expression.
#define COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH(S) \
  static_cast<int32_t>(recursive_hash<sizeof(S) - 1>(S))

constexpr int TRAFFIC_ANNOTATION_UNINITIALIZED = -1;

}  // namespace

namespace net {

// Defined types for network traffic annotation tags.
struct NetworkTrafficAnnotationTag {
  const int32_t unique_id_hash_code;

  bool operator==(const NetworkTrafficAnnotationTag& other) const {
    return unique_id_hash_code == other.unique_id_hash_code;
  }

  static NetworkTrafficAnnotationTag NotReached() {
    NOTREACHED();
    return net::NetworkTrafficAnnotationTag({TRAFFIC_ANNOTATION_UNINITIALIZED});
  }
};
struct PartialNetworkTrafficAnnotationTag {
  const int32_t unique_id_hash_code;

#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
  // |completing_id_hash_code| holds a reference to the hash coded unique id
  // of a network traffic annotation (or group id of several network traffic
  // annotations) that complete a partial network annotation. Please refer to
  // the description of DefinePartialNetworkTrafficAnnotation function for more
  // details.
  // This value is used by the clang tools to find linkage between partial
  // annotations and their completing parts, and is used in debug mode to check
  // if an intended completing part is added to a partial network annotation.
  const int32_t completing_id_hash_code;
#endif
};

// Function to convert a network traffic annotation's unique id and protobuf
// text into a NetworkTrafficAnnotationTag.
//
// This function serves as a tag that can be discovered and extracted via
// clang tools. This allows reviewing all network traffic that is generated
// and annotated by Chrome.
//
// |unique_id| should be a string that uniquely identifies this annotation
// across all of Chromium source code. |unique_id| should be kept unchanged
// as long as possible as its hashed value will be used for differnt logging,
// debugging, or auditing tasks. Unique ids should include only alphanumeric
// characters and underline.
// |proto| is a text-encoded NetworkTrafficAnnotation protobuf (see
// tools/traffic_annotation/traffic_annotation.proto)
//
// An empty and a sample template for the text-encoded protobuf can be found in
// tools/traffic_annotation/sample_traffic_annotation.cc.
// TODO(crbug.com/690323): Add tools to check annotation text's format during
// presubmit checks.
template <size_t N1, size_t N2>
constexpr NetworkTrafficAnnotationTag DefineNetworkTrafficAnnotation(
    const char (&unique_id)[N1],
    const char (&proto)[N2]) {
  return NetworkTrafficAnnotationTag(
      {COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH(unique_id)});
}

// There are cases where the network traffic annotation cannot be fully
// specified in one place. For example, in one place we know the trigger of a
// network request and in another place we know the data that will be sent. In
// these cases, we prefer that both parts of the annotation appear in context so
// that they are updated if code changes. The following functions help splitting
// the network traffic annotation into two pieces. Please refer to
// tools/traffic_annotation/sample_traffic_annotation.cc for usage samples.

// This function can be used to define a partial annotation that will be
// completed later. The completing annotation can be defined with either of
// 'CompleteNetworkTrafficAnnotation' or
// 'BranchedCompleteNetworkTrafficAnnotation' functions. In case of
// CompleteNetworkTrafficAnnotation, |completing_id| is the unique id of the
// annotation that will complete it. In the case of
// BranchedCompleteNetworkTrafficAnnotation, |completing_id| is the group id
// of the completing annotations.
template <size_t N1, size_t N2, size_t N3>
constexpr PartialNetworkTrafficAnnotationTag
DefinePartialNetworkTrafficAnnotation(const char (&unique_id)[N1],
                                      const char (&completing_id)[N2],
                                      const char (&proto)[N3]) {
#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
  return PartialNetworkTrafficAnnotationTag(
      {COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH(unique_id),
       COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH(completing_id)});
#else
  return PartialNetworkTrafficAnnotationTag(
      {COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH(unique_id)});
#endif
}

// This function can be used to define a completing partial annotation. This
// annotation adds details to another annotation that is defined before.
// |partial_annotation| is the PartialNetworkTrafficAnnotationTag returned
// by a call to DefinePartialNetworkTrafficAnnotation().
template <size_t N1, size_t N2>
NetworkTrafficAnnotationTag CompleteNetworkTrafficAnnotation(
    const char (&unique_id)[N1],
    const PartialNetworkTrafficAnnotationTag& partial_annotation,
    const char (&proto)[N2]) {
#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
  DCHECK(partial_annotation.completing_id_hash_code ==
             COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH(unique_id) ||
         partial_annotation.unique_id_hash_code ==
             COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("test_partial") ||
         partial_annotation.unique_id_hash_code ==
             COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("undefined"));
#endif
  return NetworkTrafficAnnotationTag({partial_annotation.unique_id_hash_code});
}

// This function can be used to define a completing partial annotation that is
// branched into several annotations. In this case, |group_id| is a common id
// that is used by all members of the branch and referenced by partial
// annotation that is completed by them.
template <size_t N1, size_t N2, size_t N3>
NetworkTrafficAnnotationTag BranchedCompleteNetworkTrafficAnnotation(
    const char (&unique_id)[N1],
    const char (&group_id)[N2],
    const PartialNetworkTrafficAnnotationTag& partial_annotation,
    const char (&proto)[N3]) {
#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
  DCHECK(partial_annotation.completing_id_hash_code ==
             COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH(unique_id) ||
         partial_annotation.unique_id_hash_code ==
             COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("test_partial") ||
         partial_annotation.unique_id_hash_code ==
             COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("undefined"));
#endif
  return NetworkTrafficAnnotationTag(
      {COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH(unique_id)});
}

// Example for joining N x 1 partial annotations:
// N functions foo1(), ..., fooN() call one function bar(). Each
// foo...() function defines part of a network traffic annotation.
// These N partial annotations are combined with a second part in
// bar().
//
// void foo1() {
//   auto tag = DefinePartialNetworkTrafficAnnotation(
//       "call_by_foo1", "completion_by_bar", [partial_proto]);
//   bar(tag);
// }
// void foo2() {
//   auto tag = DefinePartialNetworkTrafficAnnotation(
//       "call_by_foo2", "completion_by_bar", [partial_proto]);
//   bar(tag);
// }
// void bar(PartialNetworkTrafficAnnotationTag tag) {
//   auto final_tag = CompleteNetworkTrafficAnnotation(
//     "completion_by_bar", tag, [rest_of_proto]);
//   // final_tag matches the value of tag (which is hash code of
//   // "call_by_fooX" where X can be 1 or 2).
//   net::URLFetcher::Create(..., final_tag);
// }

// Example for joining 1 x N partial annotations:
// A function foo() calls a function bar(bool param), that sends
// different network requests depending on param. Both functions
// define parts of the network traffic annotation.
//
// void foo(bool param) {
//   auto tag = DefinePartialNetworkTrafficAnnotation(
//       "call_by_foo1", "completion_by_bar", [partial_proto]);
//   bar(param, tag);
// }
// void bar(bool param, PartialNetworkTrafficAnnotationTag tag) {
//   if (param) {
//     auto final_tag = BranchedCompleteNetworkTrafficAnnotation(
//       "call_bool_branch_1", "completion_by_bar", tag, [rest_of_proto]);
//     // final_tag is hash code of "call_bool_branch_1".
//     net::URLFetcher::Create(url1, ..., final_tag);
//   } else {
//     auto final_tag = BranchedCompleteNetworkTrafficAnnotation(
//       "call_bool_branch_2", "completion_by_bar", tag, [rest_of_proto]);
//     // final_tag is hash code of "call_bool_branch_2".
//     net::URLFetcher::Create(url2, ..., final_tag);
//   }
// }

// Please do not use this unless uninitialized annotations are required.
// Mojo interfaces for this class and the next one are defined in
// '/services/network/public/mojom'.
struct MutableNetworkTrafficAnnotationTag {
  MutableNetworkTrafficAnnotationTag()
      : unique_id_hash_code(TRAFFIC_ANNOTATION_UNINITIALIZED) {}
  explicit MutableNetworkTrafficAnnotationTag(
      const NetworkTrafficAnnotationTag& traffic_annotation)
      : unique_id_hash_code(traffic_annotation.unique_id_hash_code) {}

  int32_t unique_id_hash_code;

  bool operator==(const MutableNetworkTrafficAnnotationTag& other) const {
    return unique_id_hash_code == other.unique_id_hash_code;
  }

  explicit operator NetworkTrafficAnnotationTag() const {
    DCHECK(is_valid());
    return NetworkTrafficAnnotationTag({unique_id_hash_code});
  }

  bool is_valid() const {
    return unique_id_hash_code != TRAFFIC_ANNOTATION_UNINITIALIZED;
  }

  void reset() { unique_id_hash_code = TRAFFIC_ANNOTATION_UNINITIALIZED; }
};

struct MutablePartialNetworkTrafficAnnotationTag {
#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
  MutablePartialNetworkTrafficAnnotationTag()
      : unique_id_hash_code(TRAFFIC_ANNOTATION_UNINITIALIZED),
        completing_id_hash_code(TRAFFIC_ANNOTATION_UNINITIALIZED) {}
  explicit MutablePartialNetworkTrafficAnnotationTag(
      const PartialNetworkTrafficAnnotationTag& partial_traffic_annotation)
      : unique_id_hash_code(partial_traffic_annotation.unique_id_hash_code),
        completing_id_hash_code(
            partial_traffic_annotation.completing_id_hash_code) {}

  int32_t unique_id_hash_code;
  int32_t completing_id_hash_code;

  explicit operator PartialNetworkTrafficAnnotationTag() const {
    DCHECK(is_valid());
    return PartialNetworkTrafficAnnotationTag(
        {unique_id_hash_code, completing_id_hash_code});
  }

  bool is_valid() const {
    return unique_id_hash_code != TRAFFIC_ANNOTATION_UNINITIALIZED &&
           completing_id_hash_code != TRAFFIC_ANNOTATION_UNINITIALIZED;
  }

  void reset() {
    unique_id_hash_code = TRAFFIC_ANNOTATION_UNINITIALIZED;
    completing_id_hash_code = TRAFFIC_ANNOTATION_UNINITIALIZED;
  }
#else
  MutablePartialNetworkTrafficAnnotationTag()
      : unique_id_hash_code(TRAFFIC_ANNOTATION_UNINITIALIZED) {}
  explicit MutablePartialNetworkTrafficAnnotationTag(
      const PartialNetworkTrafficAnnotationTag& partial_traffic_annotation)
      : unique_id_hash_code(partial_traffic_annotation.unique_id_hash_code) {}

  int32_t unique_id_hash_code;

  explicit operator PartialNetworkTrafficAnnotationTag() const {
    return PartialNetworkTrafficAnnotationTag({unique_id_hash_code});
  }

  bool is_valid() const {
    return unique_id_hash_code != TRAFFIC_ANNOTATION_UNINITIALIZED;
  }

  void reset() { unique_id_hash_code = TRAFFIC_ANNOTATION_UNINITIALIZED; }
#endif  // !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
};

}  // namespace net

// Placeholder for unannotated usages.
#if !defined(OS_WIN) && !defined(OS_LINUX) && !defined(OS_CHROMEOS)
#define TRAFFIC_ANNOTATION_WITHOUT_PROTO(ANNOTATION_ID) \
  net::DefineNetworkTrafficAnnotation(ANNOTATION_ID, "No proto yet.")
#endif

#define NO_TRAFFIC_ANNOTATION_YET \
  net::DefineNetworkTrafficAnnotation("undefined", "Nothing here yet.")

#define NO_PARTIAL_TRAFFIC_ANNOTATION_YET                              \
  net::DefinePartialNetworkTrafficAnnotation("undefined", "undefined", \
                                             "Nothing here yet.")

#define MISSING_TRAFFIC_ANNOTATION     \
  net::DefineNetworkTrafficAnnotation( \
      "missing", "Function called without traffic annotation.")

#endif  // NET_TRAFFIC_ANNOTATION_NETWORK_TRAFFIC_ANNOTATION_H_
