// Copyright 2020 The Fuchsia 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 SRC_LIB_FIDL_CODEC_SEMANTIC_H_
#define SRC_LIB_FIDL_CODEC_SEMANTIC_H_

#include <map>
#include <memory>
#include <optional>
#include <ostream>
#include <string>
#include <vector>

#include "src/lib/fidl_codec/printer.h"

namespace fidl_codec {

class Type;
class PayloadableValue;
class Value;

namespace semantic {

class ExpressionValue;
class HandleSemantic;

// The context type (the kind of syscall).
enum class ContextType { kRead, kWrite, kCall };

// Context used during the execution of semantic rules.
class SemanticContext {
 public:
  SemanticContext(const HandleSemantic* handle_semantic, zx_koid_t pid, zx_handle_t handle,
                  const PayloadableValue* request, const PayloadableValue* response,
                  int64_t timestamp)
      : handle_semantic_(handle_semantic),
        pid_(pid),
        handle_(handle),
        request_(request),
        response_(response),
        timestamp_(timestamp) {}

  const HandleSemantic* handle_semantic() const { return handle_semantic_; }
  zx_koid_t pid() const { return pid_; }
  zx_handle_t handle() const { return handle_; }
  const PayloadableValue* request() const { return request_; }
  const PayloadableValue* response() const { return response_; }
  int64_t timestamp() const { return timestamp_; }

 private:
  // The semantic rules for the FIDL method.
  const HandleSemantic* const handle_semantic_;
  // The process id.
  const zx_koid_t pid_;
  // The handle we are reading/writing on.
  const zx_handle_t handle_;
  // The request (can be null).
  const PayloadableValue* const request_;
  // The response (can be null).
  const PayloadableValue* const response_;
  // The timestamp associated with the context.
  const int64_t timestamp_;
};

// Context used during the execution of semantic rules.
class AssignmentSemanticContext : public SemanticContext {
 public:
  AssignmentSemanticContext(HandleSemantic* handle_semantic, zx_koid_t pid, zx_koid_t tid,
                            zx_handle_t handle, ContextType type, const PayloadableValue* request,
                            const PayloadableValue* response, int64_t timestamp)
      : SemanticContext(handle_semantic, pid, handle, request, response, timestamp),
        tid_(tid),
        type_(type) {}

  zx_koid_t tid() const { return tid_; }
  ContextType type() const { return type_; }
  HandleSemantic* handle_semantic() const {
    return const_cast<HandleSemantic*>(SemanticContext::handle_semantic());
  }

 private:
  // The thread id.
  const zx_koid_t tid_;
  // The context type.
  const ContextType type_;
};

// Base class for all expressions (for semantic).
class Expression {
 public:
  Expression() = default;
  virtual ~Expression() = default;

  // Dump the expression.
  virtual void Dump(std::ostream& os) const = 0;

  // Execute the expression for a gien context.
  virtual bool Execute(SemanticContext* context, ExpressionValue* result) const = 0;
};

inline std::ostream& operator<<(std::ostream& os, const Expression& expression) {
  expression.Dump(os);
  return os;
}

// Defines a string literal.
class ExpressionStringLiteral : public Expression {
 public:
  ExpressionStringLiteral(std::string value) : value_(std::move(value)) {}

  void Dump(std::ostream& os) const override;
  bool Execute(SemanticContext* context, ExpressionValue* result) const override;

 private:
  const std::string value_;
};

// Defines an expression which accesses the request object.
class ExpressionRequest : public Expression {
 public:
  ExpressionRequest() = default;

  void Dump(std::ostream& os) const override;
  bool Execute(SemanticContext* context, ExpressionValue* result) const override;
};

// Defines an expression which accesses the handle used to read/write the request.
class ExpressionHandle : public Expression {
 public:
  ExpressionHandle() = default;

  void Dump(std::ostream& os) const override;
  bool Execute(SemanticContext* context, ExpressionValue* result) const override;
};

// Defines a handle description definition.
class ExpressionHandleDescription : public Expression {
 public:
  ExpressionHandleDescription(std::unique_ptr<Expression> type, std::unique_ptr<Expression> path)
      : type_(std::move(type)), path_(std::move(path)) {}

  void Dump(std::ostream& os) const override;
  bool Execute(SemanticContext* context, ExpressionValue* result) const override;

 private:
  std::unique_ptr<Expression> type_;
  std::unique_ptr<Expression> path_;
};

// Defines the access to an object field.
class ExpressionFieldAccess : public Expression {
 public:
  ExpressionFieldAccess(std::unique_ptr<Expression> expression, std::string_view field)
      : expression_(std::move(expression)), field_(field) {}

  void Dump(std::ostream& os) const override;
  bool Execute(SemanticContext* context, ExpressionValue* result) const override;

 private:
  const std::unique_ptr<Expression> expression_;
  const std::string field_;
};

// Defines the slash operator (used to concatenate two paths).
class ExpressionSlash : public Expression {
 public:
  ExpressionSlash(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right)
      : left_(std::move(left)), right_(std::move(right)) {}

  void Dump(std::ostream& os) const override;
  bool Execute(SemanticContext* context, ExpressionValue* result) const override;

 private:
  const std::unique_ptr<Expression> left_;
  const std::unique_ptr<Expression> right_;
};

// Defines the colon operator (used to add attributes to a handle).
class ExpressionColon : public Expression {
 public:
  ExpressionColon(std::unique_ptr<Expression> left, std::unique_ptr<Expression> right)
      : left_(std::move(left)), right_(std::move(right)) {}

  void Dump(std::ostream& os) const override;
  bool Execute(SemanticContext* context, ExpressionValue* result) const override;

 private:
  const std::unique_ptr<Expression> left_;
  const std::unique_ptr<Expression> right_;
};

// Defines an assignment. An assignment is a rule which infers the semantic of one handle
// (destination) using the value of an expression (source).
class Assignment {
 public:
  Assignment(std::unique_ptr<Expression> destination, std::unique_ptr<Expression> source)
      : destination_(std::move(destination)), source_(std::move(source)) {}

  void Dump(std::ostream& os) const;
  void Execute(AssignmentSemanticContext* context) const;

 private:
  const std::unique_ptr<Expression> destination_;
  const std::unique_ptr<Expression> source_;
};

// Defines the semantic associated to a method. When a method is called, all the semantic rules
// (the assignments) are executed and add knowledge about the handles involved.
class MethodSemantic {
 public:
  MethodSemantic() = default;

  void AddAssignment(std::unique_ptr<Expression> destination, std::unique_ptr<Expression> source) {
    assignments_.emplace_back(
        std::make_unique<Assignment>(std::move(destination), std::move(source)));
  }

  void Dump(std::ostream& os) const;
  void ExecuteAssignments(AssignmentSemanticContext* context) const;

 private:
  std::vector<std::unique_ptr<Assignment>> assignments_;
};

// Defines an expression to be displayed.
class DisplayExpression {
 public:
  DisplayExpression() = default;

  void set_header(std::string&& header) { header_ = std::move(header); }

  void set_expression(std::unique_ptr<Expression> expression) {
    expression_ = std::move(expression);
  }

  void set_footer(std::string&& footer) { footer_ = std::move(footer); }

  void Dump(std::ostream& os) const;
  void PrettyPrint(PrettyPrinter& printer, SemanticContext* context);

 private:
  std::string header_;
  std::unique_ptr<Expression> expression_;
  std::string footer_;
};

// Defines what needs to be display for a method. This is used to display short views of methods.
class MethodDisplay {
 public:
  MethodDisplay() = default;

  const std::vector<std::unique_ptr<DisplayExpression>>& inputs() const { return inputs_; }
  const std::vector<std::unique_ptr<DisplayExpression>>& results() const { return results_; }

  void AddInput(std::unique_ptr<DisplayExpression> input) {
    inputs_.emplace_back(std::move(input));
  }

  void AddResult(std::unique_ptr<DisplayExpression> result) {
    results_.emplace_back(std::move(result));
  }

  void Dump(std::ostream& os) const;

 private:
  std::vector<std::unique_ptr<DisplayExpression>> inputs_;
  std::vector<std::unique_ptr<DisplayExpression>> results_;
};

// Holds the information we have inferred for a handle.
// Usually we can associate a type to a handle.
// Depending on the type, we can also associate:
// - a path (for example for directories and files).
// - a file descriptor (for example for sockets).
class InferredHandleInfo {
 public:
  InferredHandleInfo() = default;

  explicit InferredHandleInfo(std::string_view type) : type_(type) {}

  InferredHandleInfo(std::string_view type, int64_t fd, std::string_view attributes)
      : type_(type), fd_(fd), attributes_(attributes) {}

  InferredHandleInfo(std::string_view type, std::string_view path, std::string_view attributes)
      : type_(type), path_(path), attributes_(attributes) {}

  InferredHandleInfo(std::string_view type, int64_t fd, std::string_view path,
                     std::string_view attributes)
      : type_(type), fd_(fd), path_(path), attributes_(attributes) {}

  const std::string& type() const { return type_; }
  int64_t fd() const { return fd_; }
  const std::string& path() const { return path_; }
  const std::string& attributes() const { return attributes_; }

  // Convert a handle type (found in zircon/system/public/zircon/processargs.h) into a string.
  static std::string_view Convert(uint32_t type);

  // Display the information we have about a handle.
  void Display(PrettyPrinter& printer) const;

 private:
  // Type of the handle. This can be a predefined type (when set by Convert) or
  // any string when it is an applicative type.
  const std::string type_;
  // Numerical value associated with the handle. Mostly used by file descriptors.
  const int64_t fd_ = -1;
  // Path associated with the handle. We can have both fd and path defined at the
  // same time.
  const std::string path_;
  // Applicative attributes associated with the handle.
  const std::string attributes_;
};

// Holds the handle semantic for one process. That is all the meaningful information we have been
// able to infer for the handles owned by one process.
struct ProcessSemantic {
  // All the handles for which we have some information.
  std::map<zx_handle_t, std::unique_ptr<InferredHandleInfo>> handles;
  // All the links between handle pairs.
  std::map<zx_handle_t, zx_handle_t> linked_handles;
};

// Object which hold the information we have about handles for all the processes.
class HandleSemantic {
 public:
  HandleSemantic() = default;
  virtual ~HandleSemantic() = default;

  const std::map<zx_koid_t, ProcessSemantic>& process_handles() const { return process_handles_; }
  const std::map<zx_koid_t, zx_koid_t>& linked_koids() const { return linked_koids_; }

  size_t handle_size(zx_koid_t pid) const {
    const auto& process_semantic = process_handles_.find(pid);
    if (process_semantic == process_handles_.end()) {
      return 0;
    }
    return process_semantic->second.handles.size();
  }

  const ProcessSemantic* GetProcessSemantic(zx_koid_t pid) const {
    const auto& process_semantic = process_handles_.find(pid);
    if (process_semantic == process_handles_.end()) {
      return nullptr;
    }
    return &process_semantic->second;
  }

  InferredHandleInfo* GetInferredHandleInfo(zx_koid_t pid, zx_handle_t handle) const {
    const auto& process_semantic = process_handles_.find(pid);
    if (process_semantic == process_handles_.end()) {
      return nullptr;
    }
    const auto& result = process_semantic->second.handles.find(handle);
    if (result == process_semantic->second.handles.end()) {
      return nullptr;
    }
    return result->second.get();
  }

  virtual void CreateHandleInfo(int64_t timestamp, zx_koid_t thread_koid, zx_handle_t handle) {}

  virtual bool NeedsToLoadHandleInfo(int64_t timestamp, zx_koid_t tid, zx_handle_t handle) const {
    return false;
  }

  void AddInferredHandleInfo(zx_koid_t pid, zx_handle_t handle,
                             const InferredHandleInfo* inferred_handle_info) {
    if (inferred_handle_info != nullptr) {
      process_handles_[pid].handles[handle] =
          std::make_unique<InferredHandleInfo>(*inferred_handle_info);
    }
  }

  void AddInferredHandleInfo(zx_koid_t pid, zx_handle_t handle,
                             std::unique_ptr<InferredHandleInfo> inferred_handle_info) {
    process_handles_[pid].handles[handle] = std::move(inferred_handle_info);
  }

  void AddInferredHandleInfo(zx_koid_t pid, zx_handle_t handle, std::string_view type) {
    process_handles_[pid].handles[handle] = std::make_unique<InferredHandleInfo>(type);
  }

  void AddInferredHandleInfo(zx_koid_t pid, zx_handle_t handle, std::string_view type, int64_t fd,
                             std::string_view attributes) {
    process_handles_[pid].handles[handle] =
        std::make_unique<InferredHandleInfo>(type, fd, attributes);
  }

  void AddInferredHandleInfo(zx_koid_t pid, zx_handle_t handle, std::string_view type,
                             std::string_view path, std::string_view attributes) {
    process_handles_[pid].handles[handle] =
        std::make_unique<InferredHandleInfo>(type, path, attributes);
  }

  void AddInferredHandleInfo(zx_koid_t pid, zx_handle_t handle, uint32_t type) {
    process_handles_[pid].handles[handle] =
        std::make_unique<InferredHandleInfo>(InferredHandleInfo::Convert(type));
  }

  // Returns the handle peer for a channel.
  zx_handle_t GetLinkedHandle(zx_koid_t pid, zx_handle_t handle) const {
    const auto& process_semantic = process_handles_.find(pid);
    if (process_semantic == process_handles_.end()) {
      return ZX_HANDLE_INVALID;
    }
    auto linked = process_semantic->second.linked_handles.find(handle);
    if (linked == process_semantic->second.linked_handles.end()) {
      return ZX_HANDLE_INVALID;
    }
    return linked->second;
  }

  // Associates two channels which have been created by the same zx_channel_create.
  void AddLinkedHandles(zx_koid_t pid, zx_handle_t handle0, zx_handle_t handle1) {
    ProcessSemantic& process_semantic = process_handles_[pid];
    process_semantic.linked_handles.insert(std::make_pair(handle0, handle1));
    process_semantic.linked_handles.insert(std::make_pair(handle1, handle0));
  }

  // Returns the koid of a channel peer given the channel koid).
  zx_koid_t GetLinkedKoid(zx_koid_t koid) const {
    auto linked = linked_koids_.find(koid);
    if (linked == linked_koids_.end()) {
      return ZX_KOID_INVALID;
    }
    return linked->second;
  }

  // Associates two channel koids.
  void AddLinkedKoids(zx_koid_t koid0, zx_koid_t koid1) {
    linked_koids_.insert(std::make_pair(koid0, koid1));
    linked_koids_.insert(std::make_pair(koid1, koid0));
  }

 private:
  std::map<zx_koid_t, ProcessSemantic> process_handles_;
  std::map<zx_koid_t, zx_koid_t> linked_koids_;
};

// Holds the evaluation of an expression. The value depends on kind_.
class ExpressionValue {
 public:
  ExpressionValue() = default;

  enum Kind { kUndefined, kValue, kHandle, kInferredHandleInfo, kString, kInteger };
  void set_value(const Type* value_type, const Value* value) {
    FX_DCHECK(value != nullptr);
    kind_ = kValue;
    value_type_ = value_type;
    value_ = value;
  }
  void set_handle(zx_handle_t handle) {
    kind_ = kHandle;
    handle_ = handle;
  }
  void set_inferred_handle_info(std::string_view type, int64_t fd, std::string_view path,
                                std::string_view attributes) {
    kind_ = kInferredHandleInfo;
    inferred_handle_info_ = std::make_unique<InferredHandleInfo>(type, fd, path, attributes);
  }
  void set_string(const std::string& string) {
    kind_ = kString;
    string_ = string;
  }
  void set_integer(int64_t integer) {
    kind_ = kInteger;
    integer_ = integer;
  }

  Kind kind() const { return kind_; }
  const Type* value_type() const {
    FX_DCHECK(kind_ == kValue);
    return value_type_;
  }
  const Value* value() const {
    FX_DCHECK(kind_ == kValue);
    return value_;
  }
  zx_handle_t handle() const {
    FX_DCHECK(kind_ == kHandle);
    return handle_;
  }
  const InferredHandleInfo* inferred_handle_info() const {
    FX_DCHECK(kind_ == kInferredHandleInfo);
    return inferred_handle_info_.get();
  }
  const std::string& string() const {
    FX_DCHECK(kind_ == kString);
    return string_;
  }
  int64_t integer() const {
    FX_DCHECK(kind_ == kInteger);
    return integer_;
  }

  // If the value is a handle and if the handle is linked then the value is assigned with the
  // linked handle.
  void UseLinkedHandle(const SemanticContext* context);

  void PrettyPrint(PrettyPrinter& printer);

 private:
  Kind kind_ = kUndefined;
  // If kind is kValue, value_ is a FIDL value with the type value_type_.
  const Type* value_type_ = nullptr;
  const Value* value_ = nullptr;
  // If kind is kHandle, handle_ is a handle.
  zx_handle_t handle_ = ZX_HANDLE_INVALID;
  // If kind is kInferredHandleInfo, inferred_handle_info_ is a inferred handle info.
  std::unique_ptr<InferredHandleInfo> inferred_handle_info_;
  // If kind is kString, string_ is a string.
  std::string string_;
  // If kind is kInteger, integer_ is an integer.
  int64_t integer_ = 0;
};

}  // namespace semantic
}  // namespace fidl_codec

#endif  // SRC_LIB_FIDL_CODEC_SEMANTIC_H_
