// 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_impl.h"

#include <utility>

#include <base/base64.h>
#include <base/bind.h>
#include <base/json/json_reader.h>
#include <base/json/json_writer.h>
#include <base/values.h>

namespace hermes {

SmdpImpl::SmdpImpl(const std::string& server_hostname)
    : server_hostname_(server_hostname),
      server_transport_(brillo::http::Transport::CreateDefault()),
      weak_factory_(this) {}

void SmdpImpl::InitiateAuthentication(
    const std::vector<uint8_t>& info1,
    const std::vector<uint8_t>& challenge,
    const InitiateAuthenticationCallback& data_callback,
    const ErrorCallback& error_callback) {
  std::string encoded_info1(info1.begin(), info1.end());
  base::Base64Encode(encoded_info1, &encoded_info1);
  std::string encoded_challenge(challenge.begin(), challenge.end());
  base::Base64Encode(encoded_challenge, &encoded_challenge);

  base::DictionaryValue http_params;
  http_params.SetString("euiccInfo1", encoded_info1);
  http_params.SetString("euiccChallenge", encoded_challenge);
  http_params.SetString("smdpAddress", server_hostname_);
  std::string http_body;
  base::JSONWriter::Write(http_params, &http_body);

  SendJsonRequest(
      "https://" + server_hostname_ +
          "/gsma/rsp2/es9plus/initiateAuthentication",
      http_body,
      base::Bind(&SmdpImpl::OnInitiateAuthenticationResponse,
                 weak_factory_.GetWeakPtr(), data_callback, error_callback),
      error_callback);
}

void SmdpImpl::OnHttpResponse(
    const base::Callback<void(DictionaryPtr)>& data_callback,
    const ErrorCallback& error_callback,
    brillo::http::RequestID request_id,
    std::unique_ptr<brillo::http::Response> response) {
  if (!response) {
    error_callback.Run(std::vector<uint8_t>());
    return;
  }

  std::string raw_data = response->ExtractDataAsString();

  std::unique_ptr<base::Value> result = base::JSONReader::Read(raw_data);
  if (result) {
    data_callback.Run(base::DictionaryValue::From(std::move(result)));
  } else {
    error_callback.Run(std::vector<uint8_t>());
    return;
  }
}

void SmdpImpl::OnInitiateAuthenticationResponse(
    const InitiateAuthenticationCallback& data_callback,
    const ErrorCallback& error_callback,
    std::unique_ptr<base::DictionaryValue> json_dict) {
  std::string encoded_buffer;
  std::string server_signed1;
  if (!json_dict->GetString("serverSigned1", &encoded_buffer)) {
    error_callback.Run(std::vector<uint8_t>());
    return;
  }
  base::Base64Decode(encoded_buffer, &server_signed1);

  std::string server_signature1;
  if (!json_dict->GetString("serverSignature1", &encoded_buffer)) {
    error_callback.Run(std::vector<uint8_t>());
    return;
  }
  base::Base64Decode(encoded_buffer, &server_signature1);

  std::string public_keys_to_use;
  if (!json_dict->GetString("euiccCiPKIdToBeUsed", &encoded_buffer)) {
    error_callback.Run(std::vector<uint8_t>());
    return;
  }
  base::Base64Decode(encoded_buffer, &public_keys_to_use);

  std::string server_certificate;
  if (!json_dict->GetString("serverCertificate", &encoded_buffer)) {
    error_callback.Run(std::vector<uint8_t>());
    return;
  }
  base::Base64Decode(encoded_buffer, &server_certificate);

  data_callback.Run(
      std::vector<uint8_t>(server_signed1.begin(), server_signed1.end()),
      std::vector<uint8_t>(server_signature1.begin(), server_signature1.end()),
      std::vector<uint8_t>(public_keys_to_use.begin(),
                           public_keys_to_use.end()),
      std::vector<uint8_t>(server_certificate.begin(),
                           server_certificate.end()));
}

void SmdpImpl::OnInitiateAuthenticationError(
    const ErrorCallback& error_callback,
    brillo::http::RequestID request_id,
    const brillo::Error* error) {}

void SmdpImpl::SendJsonRequest(
    const std::string& url,
    const std::string& json_data,
    const base::Callback<void(DictionaryPtr)>& data_callback,
    const ErrorCallback& error_callback) {
  brillo::ErrorPtr error = nullptr;
  brillo::http::Request request(url, brillo::http::request_type::kPost,
                                server_transport_);
  request.SetContentType("application/json");
  request.SetUserAgent("gsma-rsp-lpad");
  request.AddHeader("X-Admin-Protocol", "gsma/rsp/v2.0.0");
  request.AddRequestBody(json_data.data(), json_data.size(), &error);
  CHECK(!error);
  request.GetResponse(
      base::Bind(&SmdpImpl::OnHttpResponse, weak_factory_.GetWeakPtr(),
                 data_callback, error_callback),
      base::Bind(&SmdpImpl::OnInitiateAuthenticationError,
                 weak_factory_.GetWeakPtr(), error_callback));
}

// TODO(jruthe): update data_callback to the correct base::Callback signature
void SmdpImpl::AuthenticateClient(const std::vector<uint8_t>& data,
                                  const base::Closure& data_callback,
                                  const ErrorCallback& error_callback) const {}

}  // namespace hermes
