// 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/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("IntegerFieldConverter(%s, 0x%x)",
                            ::ToString(operator_), operand_);
}

std::string DoubleFieldConverter::ToString() const {
  return base::StringPrintf("IntegerFieldConverter(%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::DictionaryValue* const dict_value) const {
  const base::Value* value;

  CHECK(dict_value);

  if (!dict_value->Get(field_name, &value))
    return ReturnCode::FIELD_NOT_FOUND;

  switch (value->type()) {
    case base::Value::Type::DOUBLE:
      dict_value->SetString(field_name, std::to_string(value->GetDouble()));
      return ReturnCode::OK;
    case base::Value::Type::INTEGER:
      dict_value->SetString(field_name, std::to_string(value->GetInt()));
      return ReturnCode::OK;
    case base::Value::Type::NONE:
      dict_value->SetString(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::DictionaryValue* const dict_value) const {
  const base::Value* value;

  CHECK(dict_value);

  if (!dict_value->Get(field_name, &value))
    return ReturnCode::FIELD_NOT_FOUND;

  switch (value->type()) {
    case base::Value::Type::DOUBLE:
      dict_value->SetInteger(field_name, value->GetDouble());
      return ReturnCode::OK;
    case base::Value::Type::INTEGER:
      return ReturnCode::OK;
    case base::Value::Type::STRING: {
      std::string string_value = value->GetString();
      int int_value;
      if (StringToInt(string_value, &int_value)) {
        dict_value->SetInteger(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::DictionaryValue* const dict_value) const {
  const base::Value* value;

  CHECK(dict_value);

  if (!dict_value->Get(field_name, &value))
    return ReturnCode::FIELD_NOT_FOUND;

  switch (value->type()) {
    case base::Value::Type::DOUBLE:
      dict_value->SetInteger(field_name, value->GetDouble());
      return ReturnCode::OK;
    case base::Value::Type::INTEGER:
      return ReturnCode::OK;
    case base::Value::Type::STRING: {
      std::string string_value = value->GetString();
      int int_value;
      if (HexStringToInt(string_value, &int_value)) {
        dict_value->SetInteger(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 DoubleFieldConverter::Convert(
    const std::string& field_name,
    base::DictionaryValue* const dict_value) const {
  const base::Value* value;

  CHECK(dict_value);

  if (!dict_value->Get(field_name, &value))
    return ReturnCode::FIELD_NOT_FOUND;

  switch (value->type()) {
    case base::Value::Type::DOUBLE:
      return ReturnCode::OK;
    case base::Value::Type::INTEGER:
      dict_value->SetDouble(field_name, value->GetInt());
      return ReturnCode::OK;
    case base::Value::Type::STRING: {
      std::string string_value = value->GetString();
      double double_value;
      if (StringToDouble(string_value, &double_value)) {
        dict_value->SetDouble(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::DictionaryValue* const dict_value) const {
  std::string value;

  if (!dict_value->GetString(field_name, &value))
    return ReturnCode::FIELD_NOT_FOUND;

  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::DictionaryValue* const dict_value) const {
  int value;
  if (!dict_value->GetInteger(field_name, &value))
    return ReturnCode::FIELD_NOT_FOUND;

  return CheckNumber(operator_, value, operand_);
}

ReturnCode HexFieldConverter::Validate(
    const std::string& field_name,
    base::DictionaryValue* const dict_value) const {
  int value;
  if (!dict_value->GetInteger(field_name, &value))
    return ReturnCode::FIELD_NOT_FOUND;

  return CheckNumber(operator_, value, operand_);
}

ReturnCode DoubleFieldConverter::Validate(
    const std::string& field_name,
    base::DictionaryValue* const dict_value) const {
  double value;
  if (!dict_value->GetDouble(field_name, &value))
    return ReturnCode::FIELD_NOT_FOUND;

  return CheckNumber(operator_, value, operand_);
}

std::unique_ptr<ProbeResultChecker> ProbeResultChecker::FromDictionaryValue(
    const base::DictionaryValue& dict_value) {
  std::unique_ptr<ProbeResultChecker> instance{new ProbeResultChecker};

  for (base::DictionaryValue::Iterator it{dict_value}; !it.IsAtEnd();
       it.Advance()) {
    const auto& key = it.key();
    auto print_error_and_return = [&it]() {
      LOG(ERROR) << "'expect' attribute should be a DictionaryValue whose "
                 << "values are [<required:bool>, <expected_type:string>, "
                 << "<optional_validate_rule:string>], got: " << it.value();
      return nullptr;
    };

    const base::ListValue* list_value;

    if (!it.value().GetAsList(&list_value) || list_value->GetSize() < 2 ||
        list_value->GetSize() > 3) {
      return print_error_and_return();
    }

    bool required;
    if (!list_value->GetBoolean(0, &required))
      return print_error_and_return();
    auto* target =
        required ? &instance->required_fields_ : &instance->optional_fields_;

    std::string expect_type;
    if (!list_value->GetString(1, &expect_type))
      return print_error_and_return();

    std::string validate_rule;
    if (list_value->GetSize() == 3 && !list_value->GetString(2, &validate_rule))
      return print_error_and_return();

    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::DictionaryValue* 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& it : required_fields_) {
    if (!probe_result->HasKey(it.first)) {
      LOG(ERROR) << "Missing key: " << it.first;
      success = false;
      break;
    }

    auto return_code = it.second->Convert(it.first, probe_result);
    if (return_code != ReturnCode::OK) {
      const base::Value* value;

      probe_result->Get(it.first, &value);
      LOG(ERROR) << "Failed to apply " << it.second->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& it : optional_fields_) {
    if (!probe_result->HasKey(it.first))
      continue;

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

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

  return success;
}

}  // namespace runtime_probe
