// 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 <map>
#include <memory>
#include <string>
#include <utility>

#include <base/check.h>
#include <base/strings/stringprintf.h>
#include <base/strings/string_number_conversions.h>

#include "runtime_probe/probe_result_checker.h"
#include "runtime_probe/utils/type_utils.h"

namespace {
using ValidatorOperator = runtime_probe::ValidatorOperator;
using ReturnCode = runtime_probe::FieldConverter::ReturnCode;

constexpr const char* GetPrefix(ValidatorOperator op) {
  switch (op) {
    case ValidatorOperator::NOP:
      return "!nop ";
    case ValidatorOperator::RE:
      return "!re ";
    case ValidatorOperator::EQ:
      return "!eq ";
    case ValidatorOperator::NE:
      return "!ne ";
    case ValidatorOperator::GT:
      return "!gt ";
    case ValidatorOperator::GE:
      return "!ge ";
    case ValidatorOperator::LT:
      return "!lt ";
    case ValidatorOperator::LE:
      return "!le ";
    default:
      DCHECK(false) << "should never reach here";
  }
  return nullptr;
}

constexpr const char* ToString(ValidatorOperator op) {
  switch (op) {
    case ValidatorOperator::NOP:
      return "NOP";
    case ValidatorOperator::RE:
      return "RE";
    case ValidatorOperator::EQ:
      return "EQ";
    case ValidatorOperator::NE:
      return "NE";
    case ValidatorOperator::GT:
      return "GT";
    case ValidatorOperator::GE:
      return "GE";
    case ValidatorOperator::LT:
      return "LT";
    case ValidatorOperator::LE:
      return "LE";
    default:
      DCHECK(false) << "should never reach here";
  }
  return nullptr;
}

bool SplitValidateRuleString(const base::StringPiece& validate_rule,
                             ValidatorOperator* operator_,
                             base::StringPiece* operand) {
  if (validate_rule.empty()) {
    *operator_ = ValidatorOperator::NOP;
    *operand = "";
    return true;
  }

  auto first_space_idx = validate_rule.find_first_of(' ');
  auto prefix = validate_rule.substr(0, first_space_idx + 1);
  auto rest = validate_rule.substr(first_space_idx + 1);

  for (int i = 0; i < static_cast<int>(ValidatorOperator::NUM_OP); i++) {
    auto op = static_cast<ValidatorOperator>(i);
    if (prefix == GetPrefix(op)) {
      *operator_ = op;
      if (op != ValidatorOperator::NOP)  // NOP shouldn't have operand.
        *operand = rest;
      return true;
    }
  }
  return false;
}

template <typename ConverterType>
std::unique_ptr<ConverterType> BuildNumericConverter(
    const base::StringPiece& validate_rule) {
  ValidatorOperator op;
  base::StringPiece rest;

  if (SplitValidateRuleString(validate_rule, &op, &rest)) {
    if (op == ValidatorOperator::NOP)
      return std::make_unique<ConverterType>(op, 0);

    if (op == ValidatorOperator::EQ || op == ValidatorOperator::NE ||
        op == ValidatorOperator::GT || op == ValidatorOperator::GE ||
        op == ValidatorOperator::LT || op == ValidatorOperator::LE) {
      typename ConverterType::OperandType operand;
      if (ConverterType::StringToOperand(rest.as_string(), &operand)) {
        return std::make_unique<ConverterType>(op, operand);
      } else {
        LOG(ERROR) << "Can't convert to operand: " << rest.as_string();
      }
    }
  }
  LOG(ERROR) << "Invalid validate rule: " << validate_rule;
  return nullptr;
}

template <typename ValueType>
ReturnCode CheckNumber(ValidatorOperator op,
                       const ValueType lhs,
                       const ValueType rhs) {
  bool is_valid = true;
  switch (op) {
    case ValidatorOperator::NOP:
      break;
    case ValidatorOperator::EQ:
      is_valid = lhs == rhs;
      break;
    case ValidatorOperator::GE:
      is_valid = lhs >= rhs;
      break;
    case ValidatorOperator::GT:
      is_valid = lhs > rhs;
      break;
    case ValidatorOperator::LE:
      is_valid = lhs <= rhs;
      break;
    case ValidatorOperator::LT:
      is_valid = lhs < rhs;
      break;
    case ValidatorOperator::NE:
      is_valid = lhs != rhs;
      break;
    default:
      return ReturnCode::UNSUPPORTED_OPERATOR;
  }
  return is_valid ? ReturnCode::OK : ReturnCode::INVALID_VALUE;
}

}  // namespace

namespace runtime_probe {

using ReturnCode = FieldConverter::ReturnCode;

std::string StringFieldConverter::ToString() const {
  return base::StringPrintf("StringFieldConverter(%s, %s)",
                            ::ToString(operator_), operand_.c_str());
}

std::string IntegerFieldConverter::ToString() const {
  return base::StringPrintf("IntegerFieldConverter(%s, %d)",
                            ::ToString(operator_), operand_);
}

std::string HexFieldConverter::ToString() const {
  return base::StringPrintf("HexFieldConverter(%s, 0x%lx)",
                            ::ToString(operator_), operand_);
}

std::string DoubleFieldConverter::ToString() const {
  return base::StringPrintf("DoubleFieldConverter(%s, %f)",
                            ::ToString(operator_), operand_);
}

std::unique_ptr<StringFieldConverter> StringFieldConverter::Build(
    const base::StringPiece& validate_rule) {
  ValidatorOperator op;
  base::StringPiece pattern;

  if (SplitValidateRuleString(validate_rule, &op, &pattern)) {
    if (op == ValidatorOperator::NOP)
      return std::make_unique<StringFieldConverter>(op, "");

    if (op == ValidatorOperator::EQ || op == ValidatorOperator::NE) {
      return std::make_unique<StringFieldConverter>(op, pattern);
    }

    if (op == ValidatorOperator::RE) {
      auto instance = std::make_unique<StringFieldConverter>(op, pattern);
      if (instance->regex_->error().empty()) {
        // No error, the pattern is valid.
        return instance;
      }
      // Error string is set to non-empty if there are errors.
      LOG(ERROR) << "Invalid pattern: " << pattern;
      LOG(ERROR) << instance->regex_->error();
    }
  }

  LOG(ERROR) << "Invalid validate rule: " << validate_rule;
  return nullptr;
}

std::unique_ptr<IntegerFieldConverter> IntegerFieldConverter::Build(
    const base::StringPiece& validate_rule) {
  return BuildNumericConverter<IntegerFieldConverter>(validate_rule);
}

std::unique_ptr<HexFieldConverter> HexFieldConverter::Build(
    const base::StringPiece& validate_rule) {
  return BuildNumericConverter<HexFieldConverter>(validate_rule);
}

std::unique_ptr<DoubleFieldConverter> DoubleFieldConverter::Build(
    const base::StringPiece& validate_rule) {
  return BuildNumericConverter<DoubleFieldConverter>(validate_rule);
}

ReturnCode StringFieldConverter::Convert(const std::string& field_name,
                                         base::Value* dict_value) const {
  CHECK(dict_value);

  auto* value = dict_value->FindKey(field_name);
  if (!value)
    return ReturnCode::FIELD_NOT_FOUND;

  switch (value->type()) {
    case base::Value::Type::DOUBLE:
      dict_value->SetStringKey(field_name, std::to_string(value->GetDouble()));
      return ReturnCode::OK;
    case base::Value::Type::INTEGER:
      dict_value->SetStringKey(field_name, std::to_string(value->GetInt()));
      return ReturnCode::OK;
    case base::Value::Type::NONE:
      dict_value->SetStringKey(field_name, "null");
      return ReturnCode::OK;
    case base::Value::Type::STRING:
      return ReturnCode::OK;
    default:
      return ReturnCode::INCOMPATIBLE_VALUE;
  }
}

ReturnCode IntegerFieldConverter::Convert(const std::string& field_name,
                                          base::Value* dict_value) const {
  CHECK(dict_value);

  auto* value = dict_value->FindKey(field_name);
  if (!value)
    return ReturnCode::FIELD_NOT_FOUND;

  switch (value->type()) {
    case base::Value::Type::DOUBLE:
      dict_value->SetIntKey(field_name, static_cast<int>(value->GetDouble()));
      return ReturnCode::OK;
    case base::Value::Type::INTEGER:
      return ReturnCode::OK;
    case base::Value::Type::STRING: {
      const auto& string_value = value->GetString();
      OperandType int_value;
      if (StringToOperand(string_value, &int_value)) {
        dict_value->SetIntKey(field_name, int_value);
        return ReturnCode::OK;
      } else {
        LOG(ERROR) << "Failed to convert '" << string_value << "' to integer.";
        return ReturnCode::INCOMPATIBLE_VALUE;
      }
    }
    default:
      return ReturnCode::INCOMPATIBLE_VALUE;
  }
}

ReturnCode HexFieldConverter::Convert(const std::string& field_name,
                                      base::Value* dict_value) const {
  CHECK(dict_value);

  auto* value = dict_value->FindKey(field_name);
  if (!value)
    return ReturnCode::FIELD_NOT_FOUND;

  OperandType int_value;
  switch (value->type()) {
    case base::Value::Type::DOUBLE:
      dict_value->SetIntKey(field_name, static_cast<int>(value->GetDouble()));
      return ReturnCode::OK;
    case base::Value::Type::INTEGER: {
      int_value = value->GetInt();
      break;
    }
    case base::Value::Type::STRING: {
      const auto& string_value_ = value->GetString();
      if (!StringToOperand(string_value_, &int_value)) {
        LOG(ERROR) << "Failed to convert '" << string_value_ << "' to integer.";
        return ReturnCode::INCOMPATIBLE_VALUE;
      }
      break;
    }
    default:
      return ReturnCode::INCOMPATIBLE_VALUE;
  }
  // Since base::Value only supports 32-bit integer, we use string field to
  // store large integers.  We convert values to decimal strings to make
  // google::protobuf::util::JsonStringToMessage parse strings to integers
  // correctly.
  const auto string_value = base::NumberToString(int_value);
  dict_value->SetStringKey(field_name, string_value);
  return ReturnCode::OK;
}

ReturnCode DoubleFieldConverter::Convert(const std::string& field_name,
                                         base::Value* dict_value) const {
  CHECK(dict_value);

  auto* value = dict_value->FindKey(field_name);
  if (!value)
    return ReturnCode::FIELD_NOT_FOUND;

  switch (value->type()) {
    case base::Value::Type::DOUBLE:
      return ReturnCode::OK;
    case base::Value::Type::INTEGER:
      dict_value->SetDoubleKey(field_name, value->GetDouble());
      return ReturnCode::OK;
    case base::Value::Type::STRING: {
      const auto& string_value = value->GetString();
      double double_value;
      if (StringToDouble(string_value, &double_value)) {
        dict_value->SetDoubleKey(field_name, double_value);
        return ReturnCode::OK;
      } else {
        LOG(ERROR) << "Failed to convert '" << string_value << "' to double.";
        return ReturnCode::INCOMPATIBLE_VALUE;
      }
    }
    default:
      return ReturnCode::INCOMPATIBLE_VALUE;
  }
}

ReturnCode StringFieldConverter::Validate(const std::string& field_name,
                                          base::Value* dict_value) const {
  CHECK(dict_value);

  auto* value_ = dict_value->FindKey(field_name);
  if (!value_)
    return ReturnCode::FIELD_NOT_FOUND;
  if (!value_->is_string())
    return ReturnCode::INCOMPATIBLE_VALUE;

  const auto& value = value_->GetString();
  bool is_valid = true;
  switch (operator_) {
    case ValidatorOperator::NOP:
      break;
    case ValidatorOperator::EQ:
      is_valid = value == operand_;
      break;
    case ValidatorOperator::RE:
      is_valid = regex_->FullMatch(value);
      break;
    case ValidatorOperator::NE:
      is_valid = value != operand_;
      break;
    default:
      return ReturnCode::UNSUPPORTED_OPERATOR;
  }
  return is_valid ? ReturnCode::OK : ReturnCode::INVALID_VALUE;
}

ReturnCode IntegerFieldConverter::Validate(const std::string& field_name,
                                           base::Value* dict_value) const {
  CHECK(dict_value);

  auto* value_ = dict_value->FindKey(field_name);
  if (!value_)
    return ReturnCode::FIELD_NOT_FOUND;
  if (!value_->is_int())
    return ReturnCode::INCOMPATIBLE_VALUE;
  const auto value = value_->GetInt();

  return CheckNumber(operator_, value, operand_);
}

ReturnCode HexFieldConverter::Validate(const std::string& field_name,
                                       base::Value* dict_value) const {
  CHECK(dict_value);

  auto* value_ = dict_value->FindKey(field_name);
  if (!value_)
    return ReturnCode::FIELD_NOT_FOUND;
  OperandType value;
  switch (value_->type()) {
    case base::Value::Type::INTEGER: {
      value = value_->GetInt();
      break;
    }
    case base::Value::Type::STRING: {
      const auto& string_value = value_->GetString();
      if (!StringToInt64(string_value, &value))
        return ReturnCode::INCOMPATIBLE_VALUE;
      break;
    }
    default:
      return ReturnCode::INCOMPATIBLE_VALUE;
  }
  return CheckNumber(operator_, value, operand_);
}

ReturnCode DoubleFieldConverter::Validate(const std::string& field_name,
                                          base::Value* dict_value) const {
  CHECK(dict_value);

  auto* value_ = dict_value->FindKey(field_name);
  if (!value_)
    return ReturnCode::FIELD_NOT_FOUND;
  if (!value_->is_double() && !value_->is_int())
    return ReturnCode::INCOMPATIBLE_VALUE;
  const auto value = value_->GetDouble();

  return CheckNumber(operator_, value, operand_);
}

std::unique_ptr<ProbeResultChecker> ProbeResultChecker::FromValue(
    const base::Value& dict_value) {
  std::unique_ptr<ProbeResultChecker> instance{new ProbeResultChecker()};
  for (const auto& entry : dict_value.DictItems()) {
    const auto& key = entry.first;
    const auto& val = entry.second;
    auto print_error_and_return = [&val]() {
      LOG(ERROR) << "'expect' attribute should be a list whose values are"
                 << "[<required:bool>, <expected_type:string>, "
                 << "<optional_validate_rule:string>], got: " << val;
      return nullptr;
    };

    const auto& list_value = val.GetList();

    if (list_value.size() < 2 || list_value.size() > 3)
      return print_error_and_return();

    if (!list_value[0].is_bool())
      return print_error_and_return();
    bool required = list_value[0].GetBool();
    auto* target =
        required ? &instance->required_fields_ : &instance->optional_fields_;

    if (!list_value[1].is_string())
      return print_error_and_return();
    const auto& expect_type = list_value[1].GetString();

    std::string validate_rule;
    if (list_value.size() == 3) {
      if (!list_value[2].is_string())
        return print_error_and_return();
      validate_rule = list_value[2].GetString();
    }

    std::unique_ptr<FieldConverter> converter = nullptr;
    if (expect_type == "str") {
      converter = StringFieldConverter::Build(validate_rule);
    } else if (expect_type == "int") {
      converter = IntegerFieldConverter::Build(validate_rule);
    } else if (expect_type == "double") {
      converter = DoubleFieldConverter::Build(validate_rule);
    } else if (expect_type == "hex") {
      converter = HexFieldConverter::Build(validate_rule);
    }

    if (converter == nullptr) {
      LOG(ERROR) << "Cannot build converter, 'expect_type': " << expect_type
                 << ", 'validate_rule': " << validate_rule;
      return nullptr;
    } else {
      (*target)[key] = std::move(converter);
    }
  }

  return instance;
}

bool ProbeResultChecker::Apply(base::Value* probe_result) const {
  bool success = true;

  CHECK(probe_result != nullptr);

  // Try to convert and validate each required fields.
  // Any failures will cause the final result be |false|.
  for (const auto& entry : required_fields_) {
    const auto& key = entry.first;
    const auto& converter = entry.second;
    if (!probe_result->FindKey(key)) {
      DVLOG(2) << "Missing key: " << key;
      success = false;
      break;
    }

    auto return_code = converter->Convert(key, probe_result);
    if (return_code != ReturnCode::OK) {
      auto* value = probe_result->FindKey(key);
      LOG(ERROR) << "Failed to apply " << converter->ToString() << " on "
                 << *value << "(ReturnCode = " << static_cast<int>(return_code)
                 << ")";

      success = false;
      break;
    }
  }

  // |ProbeStatement| will remove this element from final results, there is no
  // need to continue.
  if (!success) {
    VLOG(3) << "probe_result = " << *probe_result;
    return false;
  }

  // Try to convert and validate each optional fields.
  // For failures, just remove them from probe_result and continue.
  for (const auto& entry : optional_fields_) {
    const auto& key = entry.first;
    const auto& converter = entry.second;
    if (!probe_result->FindKey(key))
      continue;

    auto return_code = converter->Convert(key, probe_result);
    if (return_code != ReturnCode::OK) {
      VLOG(1) << "Optional field '" << key << "' has unexpected value, "
              << "remove it from probe result.";
      probe_result->RemoveKey(key);
    }
  }

  // Now all fields should have the correct type, let's validate them.
  for (const auto& entry : required_fields_) {
    auto return_code = entry.second->Validate(entry.first, probe_result);
    if (return_code != ReturnCode::OK) {
      success = false;
      break;
    }
  }
  // Optional fields shouldn't have expect value.

  return success;
}

}  // namespace runtime_probe
