// Copyright 2022 Google LLC
//
// 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
//
//      https://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.

#include "generator/internal/forwarding_connection_generator.h"

namespace google {
namespace cloud {
namespace generator_internal {

ForwardingConnectionGenerator::ForwardingConnectionGenerator(
    google::protobuf::ServiceDescriptor const* service_descriptor,
    VarsDictionary service_vars,
    std::map<std::string, VarsDictionary> service_method_vars,
    google::protobuf::compiler::GeneratorContext* context,
    std::vector<MixinMethod> const& mixin_methods)
    : ServiceCodeGenerator("forwarding_connection_header_path",
                           service_descriptor, std::move(service_vars),
                           std::move(service_method_vars), context,
                           mixin_methods) {}

Status ForwardingConnectionGenerator::GenerateHeader() {
  HeaderPrint(CopyrightLicenseFileHeader());
  HeaderPrint(R"""(
// Generated by the Codegen C++ plugin.
// If you make any local changes, they will be lost.
// source: $proto_file_name$

#ifndef $header_include_guard$
#define $header_include_guard$

)""");

  // includes
  HeaderLocalIncludes({
      vars("forwarding_idempotency_policy_header_path"),
      vars("connection_header_path"),
  });

  auto result = HeaderOpenForwardingNamespaces();
  if (!result.ok()) return result;

  HeaderPrint(
      R"""(
/// @deprecated Use $product_namespace$::Make$connection_class_name$ directly.
using ::google::cloud::$product_namespace$::Make$connection_class_name$;

/// @deprecated Use $product_namespace$::$connection_class_name$ directly.
using ::google::cloud::$product_namespace$::$connection_class_name$;

/// @deprecated Use $product_namespace$::$limited_error_count_retry_policy_name$ directly.
using ::google::cloud::$product_namespace$::$limited_error_count_retry_policy_name$;

/// @deprecated Use $product_namespace$::$limited_time_retry_policy_name$ directly.
using ::google::cloud::$product_namespace$::$limited_time_retry_policy_name$;

/// @deprecated Use $product_namespace$::$retry_policy_name$ directly.
using ::google::cloud::$product_namespace$::$retry_policy_name$;
)""");

  // TODO(#8234): This is a special case for backwards compatibility of the
  //     streaming update function.
  if (vars().at("service_name") == "BigQueryRead") {
    // streaming updater functions
    for (auto const& method : methods()) {
      HeaderPrintMethod(
          method,
          {MethodPattern(
              {// clang-format off
     {"\n"
      "GOOGLE_CLOUD_CPP_DEPRECATED(\n"
      "    \"applications should not need this.\"\n"
      "    \" Please file a bug at https://github.com/googleapis/google-cloud-cpp\"\n"
      "    \" if you do.\")"
      "void $service_name$$method_name$StreamingUpdater(\n"
      "    $response_type$ const& response,\n"
      "    $request_type$& request);\n"}
       }, IsStreamingRead)},
               // clang-format on
          __FILE__, __LINE__);
    }
  }

  HeaderCloseNamespaces();
  // close header guard
  HeaderPrint(R"""(
#endif  // $header_include_guard$
)""");
  return {};
}

}  // namespace generator_internal
}  // namespace cloud
}  // namespace google
