// Copyright 2014 The Chromium 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 "mojo/public/cpp/bindings/tests/validation_test_input_parser.h"

#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include <limits>
#include <map>
#include <set>
#include <utility>

#include "mojo/public/c/system/macros.h"

namespace mojo {
namespace test {
namespace {

class ValidationTestInputParser {
 public:
  ValidationTestInputParser(const std::string& input,
                            std::vector<uint8_t>* data,
                            size_t* num_handles,
                            std::string* error_message);
  ~ValidationTestInputParser();

  bool Run();

 private:
  struct DataType;

  typedef std::pair<const char*, const char*> Range;

  typedef bool (ValidationTestInputParser::*ParseDataFunc)(
      const DataType& type,
      const std::string& value_string);

  struct DataType {
    const char* name;
    size_t name_size;
    size_t data_size;
    ParseDataFunc parse_data_func;
  };

  // A dist4/8 item that hasn't been matched with an anchr item.
  struct PendingDistanceItem {
    // Where this data item is located in |data_|.
    size_t pos;
    // Either 4 or 8 (bytes).
    size_t data_size;
  };

  bool GetNextItem(Range* range);

  bool ParseItem(const Range& range);

  bool ParseUnsignedInteger(const DataType& type,
                            const std::string& value_string);
  bool ParseSignedInteger(const DataType& type,
                          const std::string& value_string);
  bool ParseFloat(const DataType& type, const std::string& value_string);
  bool ParseDouble(const DataType& type, const std::string& value_string);
  bool ParseBinarySequence(const DataType& type,
                           const std::string& value_string);
  bool ParseDistance(const DataType& type, const std::string& value_string);
  bool ParseAnchor(const DataType& type, const std::string& value_string);
  bool ParseHandles(const DataType& type, const std::string& value_string);

  bool StartsWith(const Range& range, const char* prefix, size_t prefix_length);

  bool ConvertToUnsignedInteger(const std::string& value_string,
                                unsigned long long int* value);

  template <typename T>
  void AppendData(T data) {
    size_t pos = data_->size();
    data_->resize(pos + sizeof(T));
    memcpy(&(*data_)[pos], &data, sizeof(T));
  }

  template <typename TargetType, typename InputType>
  bool ConvertAndAppendData(InputType value) {
    if (value > std::numeric_limits<TargetType>::max() ||
        value < std::numeric_limits<TargetType>::min()) {
      return false;
    }
    AppendData(static_cast<TargetType>(value));
    return true;
  }

  template <typename TargetType, typename InputType>
  bool ConvertAndFillData(size_t pos, InputType value) {
    if (value > std::numeric_limits<TargetType>::max() ||
        value < std::numeric_limits<TargetType>::min()) {
      return false;
    }
    TargetType target_value = static_cast<TargetType>(value);
    assert(pos + sizeof(TargetType) <= data_->size());
    memcpy(&(*data_)[pos], &target_value, sizeof(TargetType));
    return true;
  }

  static const DataType kDataTypes[];
  static const size_t kDataTypeCount;

  const std::string& input_;
  size_t input_cursor_;

  std::vector<uint8_t>* data_;
  size_t* num_handles_;
  std::string* error_message_;

  std::map<std::string, PendingDistanceItem> pending_distance_items_;
  std::set<std::string> anchors_;
};

#define DATA_TYPE(name, data_size, parse_data_func) \
  { name, sizeof(name) - 1, data_size, parse_data_func }

const ValidationTestInputParser::DataType
    ValidationTestInputParser::kDataTypes[] = {
        DATA_TYPE("[u1]", 1, &ValidationTestInputParser::ParseUnsignedInteger),
        DATA_TYPE("[u2]", 2, &ValidationTestInputParser::ParseUnsignedInteger),
        DATA_TYPE("[u4]", 4, &ValidationTestInputParser::ParseUnsignedInteger),
        DATA_TYPE("[u8]", 8, &ValidationTestInputParser::ParseUnsignedInteger),
        DATA_TYPE("[s1]", 1, &ValidationTestInputParser::ParseSignedInteger),
        DATA_TYPE("[s2]", 2, &ValidationTestInputParser::ParseSignedInteger),
        DATA_TYPE("[s4]", 4, &ValidationTestInputParser::ParseSignedInteger),
        DATA_TYPE("[s8]", 8, &ValidationTestInputParser::ParseSignedInteger),
        DATA_TYPE("[b]", 1, &ValidationTestInputParser::ParseBinarySequence),
        DATA_TYPE("[f]", 4, &ValidationTestInputParser::ParseFloat),
        DATA_TYPE("[d]", 8, &ValidationTestInputParser::ParseDouble),
        DATA_TYPE("[dist4]", 4, &ValidationTestInputParser::ParseDistance),
        DATA_TYPE("[dist8]", 8, &ValidationTestInputParser::ParseDistance),
        DATA_TYPE("[anchr]", 0, &ValidationTestInputParser::ParseAnchor),
        DATA_TYPE("[handles]", 0, &ValidationTestInputParser::ParseHandles)};

const size_t ValidationTestInputParser::kDataTypeCount =
    sizeof(ValidationTestInputParser::kDataTypes) /
    sizeof(ValidationTestInputParser::kDataTypes[0]);

ValidationTestInputParser::ValidationTestInputParser(const std::string& input,
                                                     std::vector<uint8_t>* data,
                                                     size_t* num_handles,
                                                     std::string* error_message)
    : input_(input),
      input_cursor_(0),
      data_(data),
      num_handles_(num_handles),
      error_message_(error_message) {
  assert(data_);
  assert(num_handles_);
  assert(error_message_);
  data_->clear();
  *num_handles_ = 0;
  error_message_->clear();
}

ValidationTestInputParser::~ValidationTestInputParser() {
}

bool ValidationTestInputParser::Run() {
  Range range;
  bool result = true;
  while (result && GetNextItem(&range))
    result = ParseItem(range);

  if (!result) {
    *error_message_ =
        "Error occurred when parsing " + std::string(range.first, range.second);
  } else if (!pending_distance_items_.empty()) {
    // We have parsed all the contents in |input_| successfully, but there are
    // unmatched dist4/8 items.
    *error_message_ = "Error occurred when matching [dist4/8] and [anchr].";
    result = false;
  }
  if (!result) {
    data_->clear();
    *num_handles_ = 0;
  } else {
    assert(error_message_->empty());
  }

  return result;
}

bool ValidationTestInputParser::GetNextItem(Range* range) {
  const char kWhitespaceChars[] = " \t\n\r";
  const char kItemDelimiters[] = " \t\n\r/";
  const char kEndOfLineChars[] = "\n\r";
  while (true) {
    // Skip leading whitespaces.
    // If there are no non-whitespace characters left, |input_cursor_| will be
    // set to std::npos.
    input_cursor_ = input_.find_first_not_of(kWhitespaceChars, input_cursor_);

    if (input_cursor_ >= input_.size())
      return false;

    if (StartsWith(
            Range(&input_[0] + input_cursor_, &input_[0] + input_.size()),
            "//",
            2)) {
      // Skip contents until the end of the line.
      input_cursor_ = input_.find_first_of(kEndOfLineChars, input_cursor_);
    } else {
      range->first = &input_[0] + input_cursor_;
      input_cursor_ = input_.find_first_of(kItemDelimiters, input_cursor_);
      range->second = input_cursor_ >= input_.size()
                          ? &input_[0] + input_.size()
                          : &input_[0] + input_cursor_;
      return true;
    }
  }
  return false;
}

bool ValidationTestInputParser::ParseItem(const Range& range) {
  for (size_t i = 0; i < kDataTypeCount; ++i) {
    if (StartsWith(range, kDataTypes[i].name, kDataTypes[i].name_size)) {
      return (this->*kDataTypes[i].parse_data_func)(
          kDataTypes[i],
          std::string(range.first + kDataTypes[i].name_size, range.second));
    }
  }

  // "[u1]" is optional.
  return ParseUnsignedInteger(kDataTypes[0],
                              std::string(range.first, range.second));
}

bool ValidationTestInputParser::ParseUnsignedInteger(
    const DataType& type,
    const std::string& value_string) {
  unsigned long long int value;
  if (!ConvertToUnsignedInteger(value_string, &value))
    return false;

  switch (type.data_size) {
    case 1:
      return ConvertAndAppendData<uint8_t>(value);
    case 2:
      return ConvertAndAppendData<uint16_t>(value);
    case 4:
      return ConvertAndAppendData<uint32_t>(value);
    case 8:
      return ConvertAndAppendData<uint64_t>(value);
    default:
      assert(false);
      return false;
  }
}

bool ValidationTestInputParser::ParseSignedInteger(
    const DataType& type,
    const std::string& value_string) {
  long long int value;
  if (sscanf(value_string.c_str(), "%lli", &value) != 1)
    return false;

  switch (type.data_size) {
    case 1:
      return ConvertAndAppendData<int8_t>(value);
    case 2:
      return ConvertAndAppendData<int16_t>(value);
    case 4:
      return ConvertAndAppendData<int32_t>(value);
    case 8:
      return ConvertAndAppendData<int64_t>(value);
    default:
      assert(false);
      return false;
  }
}

bool ValidationTestInputParser::ParseFloat(const DataType& type,
                                           const std::string& value_string) {
  static_assert(sizeof(float) == 4, "sizeof(float) is not 4");

  float value;
  if (sscanf(value_string.c_str(), "%f", &value) != 1)
    return false;

  AppendData(value);
  return true;
}

bool ValidationTestInputParser::ParseDouble(const DataType& type,
                                            const std::string& value_string) {
  static_assert(sizeof(double) == 8, "sizeof(double) is not 8");

  double value;
  if (sscanf(value_string.c_str(), "%lf", &value) != 1)
    return false;

  AppendData(value);
  return true;
}

bool ValidationTestInputParser::ParseBinarySequence(
    const DataType& type,
    const std::string& value_string) {
  if (value_string.size() != 8)
    return false;

  uint8_t value = 0;
  for (std::string::const_iterator iter = value_string.begin();
       iter != value_string.end();
       ++iter) {
    value <<= 1;
    if (*iter == '1')
      value++;
    else if (*iter != '0')
      return false;
  }
  AppendData(value);
  return true;
}

bool ValidationTestInputParser::ParseDistance(const DataType& type,
                                              const std::string& value_string) {
  if (pending_distance_items_.find(value_string) !=
      pending_distance_items_.end())
    return false;

  PendingDistanceItem item = {data_->size(), type.data_size};
  data_->resize(data_->size() + type.data_size);
  pending_distance_items_[value_string] = item;

  return true;
}

bool ValidationTestInputParser::ParseAnchor(const DataType& type,
                                            const std::string& value_string) {
  if (anchors_.find(value_string) != anchors_.end())
    return false;
  anchors_.insert(value_string);

  std::map<std::string, PendingDistanceItem>::iterator iter =
      pending_distance_items_.find(value_string);
  if (iter == pending_distance_items_.end())
    return false;

  PendingDistanceItem dist_item = iter->second;
  pending_distance_items_.erase(iter);

  size_t distance = data_->size() - dist_item.pos;
  switch (dist_item.data_size) {
    case 4:
      return ConvertAndFillData<uint32_t>(dist_item.pos, distance);
    case 8:
      return ConvertAndFillData<uint64_t>(dist_item.pos, distance);
    default:
      assert(false);
      return false;
  }
}

bool ValidationTestInputParser::ParseHandles(const DataType& type,
                                             const std::string& value_string) {
  // It should be the first item.
  if (!data_->empty())
    return false;

  unsigned long long int value;
  if (!ConvertToUnsignedInteger(value_string, &value))
    return false;

  if (value > std::numeric_limits<size_t>::max())
    return false;

  *num_handles_ = static_cast<size_t>(value);
  return true;
}

bool ValidationTestInputParser::StartsWith(const Range& range,
                                           const char* prefix,
                                           size_t prefix_length) {
  if (static_cast<size_t>(range.second - range.first) < prefix_length)
    return false;

  return memcmp(range.first, prefix, prefix_length) == 0;
}

bool ValidationTestInputParser::ConvertToUnsignedInteger(
    const std::string& value_string,
    unsigned long long int* value) {
  const char* format = nullptr;
  if (value_string.find_first_of("xX") != std::string::npos)
    format = "%llx";
  else
    format = "%llu";
  return sscanf(value_string.c_str(), format, value) == 1;
}

}  // namespace

bool ParseValidationTestInput(const std::string& input,
                              std::vector<uint8_t>* data,
                              size_t* num_handles,
                              std::string* error_message) {
  ValidationTestInputParser parser(input, data, num_handles, error_message);
  return parser.Run();
}

}  // namespace test
}  // namespace mojo
