// Copyright 2014 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 <brillo/data_encoding.h>
#include <modp_b64/modp_b64.h>

#include <memory>

#include <base/logging.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <brillo/strings/string_utils.h>

namespace {

inline int HexToDec(int hex) {
  int dec = -1;
  if (hex >= '0' && hex <= '9') {
    dec = hex - '0';
  } else if (hex >= 'A' && hex <= 'F') {
    dec = hex - 'A' + 10;
  } else if (hex >= 'a' && hex <= 'f') {
    dec = hex - 'a' + 10;
  }
  return dec;
}

// Helper for Base64Encode() and Base64EncodeWrapLines().
std::string Base64EncodeHelper(const void* data, size_t size) {
  std::vector<char> buffer;
  buffer.resize(modp_b64_encode_len(size));
  size_t out_size =
      modp_b64_encode(buffer.data(), static_cast<const char*>(data), size);
  return std::string{buffer.begin(), buffer.begin() + out_size};
}

}  // namespace

/////////////////////////////////////////////////////////////////////////
namespace brillo {
namespace data_encoding {

std::string UrlEncode(const char* data, bool encodeSpaceAsPlus) {
  std::string result;

  while (*data) {
    char c = *data++;
    // According to RFC3986 (http://www.faqs.org/rfcs/rfc3986.html),
    // section 2.3. - Unreserved Characters
    if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') ||
        (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' ||
        c == '~') {
      result += c;
    } else if (c == ' ' && encodeSpaceAsPlus) {
      // For historical reasons, some URLs have spaces encoded as '+',
      // this also applies to form data encoded as
      // 'application/x-www-form-urlencoded'
      result += '+';
    } else {
      base::StringAppendF(&result, "%%%02X",
                          static_cast<unsigned char>(c));  // Encode as %NN
    }
  }
  return result;
}

std::string UrlDecode(const char* data) {
  std::string result;
  while (*data) {
    char c = *data++;
    int part1 = 0, part2 = 0;
    // HexToDec would return -1 even for character 0 (end of string),
    // so it is safe to access data[0] and data[1] without overrunning the buf.
    if (c == '%' && (part1 = HexToDec(data[0])) >= 0 &&
        (part2 = HexToDec(data[1])) >= 0) {
      c = static_cast<char>((part1 << 4) | part2);
      data += 2;
    } else if (c == '+') {
      c = ' ';
    }
    result += c;
  }
  return result;
}

std::string WebParamsEncode(const WebParamList& params,
                            bool encodeSpaceAsPlus) {
  std::vector<std::string> pairs;
  pairs.reserve(params.size());
  for (const auto& p : params) {
    std::string key = UrlEncode(p.first.c_str(), encodeSpaceAsPlus);
    std::string value = UrlEncode(p.second.c_str(), encodeSpaceAsPlus);
    pairs.push_back(brillo::string_utils::Join("=", key, value));
  }

  return brillo::string_utils::Join("&", pairs);
}

WebParamList WebParamsDecode(const std::string& data) {
  WebParamList result;
  std::vector<std::string> params = brillo::string_utils::Split(data, "&");
  for (const auto& p : params) {
    auto pair = brillo::string_utils::SplitAtFirst(p, "=");
    result.emplace_back(UrlDecode(pair.first.c_str()),
                        UrlDecode(pair.second.c_str()));
  }
  return result;
}

std::string Base64Encode(const void* data, size_t size) {
  return Base64EncodeHelper(data, size);
}

std::string Base64EncodeWrapLines(const void* data, size_t size) {
  std::string unwrapped = Base64EncodeHelper(data, size);
  std::string wrapped;

  for (size_t i = 0; i < unwrapped.size(); i += 64) {
    wrapped.append(unwrapped, i, 64);
    wrapped.append("\n");
  }
  return wrapped;
}

bool Base64Decode(const std::string& input, brillo::Blob* output) {
  std::string temp_buffer;
  const std::string* data = &input;
  if (input.find_first_of("\r\n") != std::string::npos) {
    base::ReplaceChars(input, "\n", "", &temp_buffer);
    base::ReplaceChars(temp_buffer, "\r", "", &temp_buffer);
    data = &temp_buffer;
  }
  // base64 decoded data has 25% fewer bytes than the original (since every
  // 3 source octets are encoded as 4 characters in base64).
  // modp_b64_decode_len provides an upper estimate of the size of the output
  // data.
  output->resize(modp_b64_decode_len(data->size()));

  size_t size_read = modp_b64_decode(reinterpret_cast<char*>(output->data()),
                                     data->data(), data->size());
  if (size_read == MODP_B64_ERROR) {
    output->resize(0);
    return false;
  }
  output->resize(size_read);

  return true;
}

}  // namespace data_encoding
}  // namespace brillo
