// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "hermes/smdp.h"

#include <algorithm>
#include <string>
#include <utility>

#include <base/base64.h>
#include <base/bind.h>
#include <base/check.h>
#include <base/files/file_path.h>
#include <base/json/json_reader.h>
#include <base/json/json_writer.h>
#include <base/logging.h>
#include <base/strings/string_util.h>
#include <base/values.h>

namespace {

constexpr auto kSmdxTimeout = base::TimeDelta::FromMinutes(3);
constexpr auto kSendNotificationsTimeout = base::TimeDelta::FromSeconds(15);
constexpr std::string_view kHandleNotification = "handleNotification";

void OnHttpsResponse(hermes::Smdp::LpaCallback cb,
                     brillo::http::RequestID /*request_id*/,
                     std::unique_ptr<brillo::http::Response> response) {
  LOG(INFO) << __func__;
  std::string raw_data;
  if (!response) {
    cb(0, raw_data, lpa::smdp::SmdpClient::kMalformedResponse);
    return;
  }

  raw_data = response->ExtractDataAsString();
  VLOG(1) << __func__ << ": Response raw_data : " << raw_data;

  cb(response->GetStatusCode(), raw_data, lpa::smdp::SmdpClient::kNoError);
}

void OnHttpsError(hermes::Smdp::LpaCallback cb,
                  brillo::http::RequestID /*request_id*/,
                  const brillo::Error* error) {
  LOG(WARNING) << "HTTPS request failed (brillo error code " << error->GetCode()
               << "): " << error->GetMessage();
  std::string empty;
  cb(0, empty, lpa::smdp::SmdpClient::kSendHttpsError);
}

}  // namespace

namespace hermes {

SmdpFactory::SmdpFactory(Logger* logger, Executor* executor)
    : logger_(logger), executor_(executor) {}

std::unique_ptr<lpa::smdp::SmdpClient> SmdpFactory::NewSmdpClient(
    std::string tls_certs_dir,
    std::string smdp_addr,
    const lpa::proto::EuiccSpecVersion& card_verison) {
  return std::make_unique<Smdp>(std::move(smdp_addr), std::move(tls_certs_dir),
                                logger_, executor_);
}

Smdp::Smdp(std::string server_addr,
           const std::string& certs_dir,
           Logger* logger,
           Executor* executor)
    : server_transport_(brillo::http::Transport::CreateDefault()),
      logger_(logger),
      executor_(executor) {
  if (certs_dir.find("/test/") != std::string::npos) {
    LOG(INFO) << "Using SSL certificates for GSMA test servers";
    server_transport_->UseCustomCertificate(
        brillo::http::Transport::Certificate::kHermesTest);
  } else {
    LOG(INFO) << "Using SSL certificates for GSMA production servers";
    server_transport_->UseCustomCertificate(
        brillo::http::Transport::Certificate::kHermesProd);
  }
  // QR codes from certain vendors have SMDP address in uppercase but reject
  // initiateAuthenticate if the domain name isn't lowercase. b/183032912
  smdp_addr_ = base::ToLowerASCII(server_addr);
  // Ensure |smdp_addr_| does not begin with a scheme (e.g. "https://"), as this
  // variable will be used for the smdpAddress field in SM-DP+ communications.
  size_t found = smdp_addr_.find("://");
  if (found != std::string::npos) {
    smdp_addr_.erase(0, found + 3);
  }
}

lpa::util::EuiccLog* Smdp::logger() {
  return logger_;
}

lpa::util::Executor* Smdp::executor() {
  return executor_;
}

void Smdp::SendHttps(const std::string& path,
                     const std::string& request,
                     LpaCallback cb) {
  // path is hardcoded by the LPA. There is no PII.
  LOG(INFO) << __func__ << " path:" << path;
  brillo::ErrorPtr error = nullptr;
  std::string url = "https://" + smdp_addr_ + path;

  if (path.find(kHandleNotification) != std::string::npos)
    server_transport_->SetDefaultTimeout(kSendNotificationsTimeout);
  else
    server_transport_->SetDefaultTimeout(kSmdxTimeout);

  VLOG(1) << __func__ << ": sending data to " << url << ": " << request;
  brillo::http::Request http_request(url, brillo::http::request_type::kPost,
                                     server_transport_);
  http_request.SetContentType("application/json");
  http_request.SetUserAgent("gsma-rsp-lpad");
  http_request.AddHeader("X-Admin-Protocol", "gsma/rsp/v2.0.0");
  http_request.AddRequestBody(&request[0], request.size(), &error);
  CHECK(!error);

  http_request.GetResponse(base::Bind(&OnHttpsResponse, cb),
                           base::Bind(&OnHttpsError, cb));
}

}  // namespace hermes
