// 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/strings/string_util.h>
#include <base/values.h>

namespace {

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;
  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
