// 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.

#ifndef RUNTIME_PROBE_PROBE_RESULT_CHECKER_H_
#define RUNTIME_PROBE_PROBE_RESULT_CHECKER_H_

#include <cstdint>
#include <map>
#include <memory>
#include <string>

#include <pcrecpp.h>

#include <base/values.h>
#include <gtest/gtest.h>

#include "runtime_probe/utils/type_utils.h"

namespace runtime_probe {

enum class ValidatorOperator : uint8_t {
  NOP = 0,
  RE,  // Regular Expression match
  EQ,  // EQual to
  NE,  // Not Equal to
  GT,  // Greater Than
  GE,  // Greater than or Euqal to
  LT,  // Less Than
  LE,  // Less than or Equal to

  NUM_OP,
};

// Base class of field converter.
//
// Each derived class should implement one and only one constructor
// FieldConverter(const std::string& validate_rule).
class FieldConverter {
 public:
  enum class ReturnCode {
    OK = 0,
    FIELD_NOT_FOUND = 1,
    // Failed to convert the field
    INCOMPATIBLE_VALUE = 2,
    // The operator is not supported by this converter
    UNSUPPORTED_OPERATOR = 3,
    // Field value is invalid
    INVALID_VALUE = 4,
  };

  // Try to find |field_name| in |dict_value|, and convert it to expected type.
  //
  // @return |ReturnCode| to indicate success or reason of failure.
  virtual ReturnCode Convert(const std::string& field_name,
                             base::Value* dict_value) const = 0;

  // Check if value of |field_name| in dict_value is valid.
  //
  // @return |ReturnCode| to indicate success or reason of failure.
  virtual ReturnCode Validate(const std::string& field_name,
                              base::Value* dict_value) const = 0;

  virtual std::string ToString() const = 0;

  virtual ~FieldConverter() = default;
};

// Convert a field to string.
//
// Supported validators:
//   - "!re <Perl-compatible regular expression>"
//   - "!eq <expected string>"
//   - "!ne <unexpected string>"
class StringFieldConverter : public FieldConverter {
 public:
  ReturnCode Convert(const std::string& field_name,
                     base::Value* dict_value) const override;

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

  std::string ToString() const override;

  static std::unique_ptr<StringFieldConverter> Build(
      const base::StringPiece& validate_rule);

  StringFieldConverter(ValidatorOperator op, const base::StringPiece& operand)
      : operator_(op), operand_(operand) {
    if (op == ValidatorOperator::RE) {
      // pcrecpp::RE constructor will always succeed, but might set "error()" if
      // the pattern is invalid.  This will be checked in |Build()|.
      regex_ = std::make_unique<pcrecpp::RE>(operand.as_string());
    }
  }

 private:
  ValidatorOperator operator_;
  std::string operand_;
  std::unique_ptr<pcrecpp::RE> regex_;

  FRIEND_TEST(StringFieldConverterTest, TestValidateRule);
};

// Numeric Field Converters convert a field into a numeric type.
// The logic of these fields are very similar.  To allow implementing common
// logic with template, helper function |StringToOperand| and type alias
// |OperandType| is defined.  |OperandType| is the type of |operand_| member
// variable.  And |StringToOperand| converts a string to |OperandType| value
// and return true on success.

// Convert a field to integer.
//
// However, heximal value is not allowed, please use |HexFieldConverter|
// instead.
//
// Supported validators:
//   - "!eq <integer>"
//   - "!ne <integer>"
//   - "!gt <integer>"
//   - "!ge <integer>"
//   - "!lt <integer>"
//   - "!le <integer>"
class IntegerFieldConverter : public FieldConverter {
 public:
  using FieldConverter::FieldConverter;
  using OperandType = int;

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

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

  std::string ToString() const override;

  static std::unique_ptr<IntegerFieldConverter> Build(
      const base::StringPiece& validate_rule);

  IntegerFieldConverter(ValidatorOperator op, OperandType operand)
      : operator_(op), operand_(operand) {}

  static bool StringToOperand(const std::string& s, OperandType* output) {
    return StringToInt(s, output);
  }

 private:
  ValidatorOperator operator_;
  OperandType operand_;

  FRIEND_TEST(IntegerFieldConverterTest, TestValidateRule);
};

// Convert a hex string field to integer.
//
// If the original field is string, this class assumes it is base 16.
// Otherwise, if the field is already a number (int or double), the behavior wil
// be identical to |IntegerFieldConverter|.
//
// Supported validators: same as |IntegerFieldConverter|
class HexFieldConverter : public FieldConverter {
 public:
  using FieldConverter::FieldConverter;
  using OperandType = int;

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

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

  std::string ToString() const override;

  static std::unique_ptr<HexFieldConverter> Build(
      const base::StringPiece& validate_rule);

  HexFieldConverter(ValidatorOperator op, OperandType operand)
      : operator_(op), operand_(operand) {}

  static bool StringToOperand(const std::string& s, OperandType* output) {
    return HexStringToInt(s, output);
  }

 private:
  ValidatorOperator operator_;
  OperandType operand_;

  FRIEND_TEST(HexFieldConverterTest, TestValidateRule);
};

// Convert a field to double.
//
// Supported validators: same as |IntegerFieldConverter|, except the operand
// could be double.
class DoubleFieldConverter : public FieldConverter {
 public:
  using FieldConverter::FieldConverter;
  using OperandType = double;

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

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

  std::string ToString() const override;

  static std::unique_ptr<DoubleFieldConverter> Build(
      const base::StringPiece& validate_rule);

  DoubleFieldConverter(ValidatorOperator op, OperandType operand)
      : operator_(op), operand_(operand) {}

  static bool StringToOperand(const std::string& s, OperandType* output) {
    return StringToDouble(s, output);
  }

 private:
  ValidatorOperator operator_;
  OperandType operand_;

  FRIEND_TEST(DoubleFieldConverterTest, TestValidateRule);
};

// Holds |expect| attribute of a |ProbeStatement|.
//
// |expect| attribute should be a |Value| with following format:
// {
//   <key_of_probe_result>: [<required:bool>, <expected_type:string>,
//                           <optional_validate_rule:string>]
// }
//
// Currently, we support the following expected types:
// - "int"  (use |IntegerFieldConverter|)
// - "hex"  (use |HexFieldConverter|)
// - "double"  (use |DoubleFieldConverter|)
// - "str"  (use |StringFieldConverter|)
//
// |ProbeResultChecker| will first try to convert each field to |expected_type|.
// Then, if |optional_validate_rule| is given, will check if converted value
// match the rule.
//
// TODO(b/121354690): Handle |optional_validate_rule|.
class ProbeResultChecker {
 public:
  static std::unique_ptr<ProbeResultChecker> FromValue(
      const base::Value& dict_value);

  // Apply |expect| rules to |probe_result|
  //
  // @return |true| if all required fields are converted successfully.
  bool Apply(base::Value* probe_result) const;

 private:
  std::map<std::string, std::unique_ptr<FieldConverter>> required_fields_;
  std::map<std::string, std::unique_ptr<FieldConverter>> optional_fields_;

  FRIEND_TEST(ProbeResultCheckerTest, TestFromValue);
};

}  // namespace runtime_probe

#endif  // RUNTIME_PROBE_PROBE_RESULT_CHECKER_H_
