// 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_FUNCTION_H_
#define RUNTIME_PROBE_PROBE_FUNCTION_H_

#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <type_traits>
#include <utility>
#include <variant>
#include <vector>

#include <base/json/json_writer.h>
#include <base/values.h>
#include <base/strings/string_util.h>

#include "runtime_probe/probe_function_argument.h"

namespace runtime_probe {

class ProbeFunction {
  // Formally, a probe function will be represented as following structure::
  //   {
  //     <function_name:string>: <args:ArgsType>
  //   }
  //
  // where the top layer dictionary should have one and only one key.  For
  // example::
  //   {
  //     "sysfs": {
  //       "dir_path": "/sys/class/cool/device/dev*",
  //       "keys": ["key_1", "key_2"],
  //       "optional_keys": ["opt_key_1"]
  //     }
  //   }
  //
  // TODO(stimim): implement the following syntax.
  //
  // Alternative Syntax::
  //   1. single string ("<function_name:string>"), this is equivalent to::
  //      {
  //        <function_name:string>: {}
  //      }
  //
  //   2. single string ("<function_name:string>:<arg:string>"), this is
  //      equivalent to::
  //      {
  //        <function_name:string>: {
  //          "__only_required_argument": {
  //            <arg:string>
  //          }
  //        }
  //      }

 public:
  using DataType = std::vector<base::DictionaryValue>;

  // Convert |value| to ProbeFunction.  Returns nullptr on failure.
  static std::unique_ptr<ProbeFunction> FromValue(const base::Value& value) {
    std::unique_ptr<ProbeFunction> retval;

    if (value.is_dict()) {
      const base::DictionaryValue* dict_value;
      value.GetAsDictionary(&dict_value);
      retval = FromDictionaryValue(*dict_value);
    }

    if (retval == nullptr) {
      LOG(ERROR) << "Failed to parse " << value << " as ProbeFunction";
    }
    return retval;
  }

  virtual std::string GetFunctionName() const { return {}; }

  // Evaluates this entire probe function.
  //
  // Output will be a list of base::DictionaryValue.
  virtual DataType Eval() const = 0;

  // Serializes this probe function and passes it to helper. The output of the
  // helper will store in |result|.
  //
  // true if success on executing helper.
  bool InvokeHelper(std::string* result) const;

  // Evaluates the helper part for this probe function. Helper part is
  // designed for portion that need extended sandbox. ProbeFunction will
  // be initialized with same json statement in the helper process, which
  // invokes EvalInHelper() instead of Eval(). Since execution of
  // EvalInHelper() implies a different sandbox, it is encouraged to keep work
  // that doesn't need a privilege out of this function.
  //
  // Output will be an integer and the interpretation of the integer on
  // purposely leaves to the caller because it might execute other binary
  // in sandbox environment and we might want to preserve the exit code.
  virtual int EvalInHelper(std::string* output) const;

  // Function prototype of |FromDictionaryValue| that should be implemented by
  // each derived class.  See `functions/sysfs.h` about how to implement this
  // function.
  using FactoryFunctionType = std::function<std::unique_ptr<ProbeFunction>(
      const base::DictionaryValue&)>;

  // Mapping from |function_name| to |FromDictionaryValue| of each derived
  // classes.
  static std::map<std::string_view, FactoryFunctionType> registered_functions_;

  template <class T>
  struct Register {
    Register() {
      static_assert(std::is_base_of<ProbeFunction, T>::value,
                    "Registered type must inherit ProbeFunction");
      registered_functions_[T::function_name] = T::FromDictionaryValue;
    }
  };

  virtual ~ProbeFunction() = default;

 protected:
  ProbeFunction() = default;

 private:
  static std::unique_ptr<ProbeFunction> FromDictionaryValue(
      const base::DictionaryValue& dict_value);
  std::unique_ptr<base::DictionaryValue> raw_value_;

  // Each probe function must define their own args type.
};

#ifdef _RUNTIME_PROBE_GENERATE_PROBE_FUNCTIONS
// _RUNTIME_PROBE_GENERATE_PROBE_FUNCTIONS should only be defined by
// `all_functions.cc`.  So the following initialization will only have one
// instance.

std::map<std::string_view, ProbeFunction::FactoryFunctionType>
    ProbeFunction::registered_functions_{};
#define REGISTER_PROBE_FUNCTION(T) ProbeFunction::Register<T> T::register_

#else

#define REGISTER_PROBE_FUNCTION(T)

#endif

}  // namespace runtime_probe

#endif  // RUNTIME_PROBE_PROBE_FUNCTION_H_
