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

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

#include <zircon/processargs.h>
#include <zircon/types.h>

#include <string>

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

namespace fidl_codec {
namespace semantic {

void ExpressionStringLiteral::Dump(std::ostream& os) const { os << '\'' << value_ << '\''; }

bool ExpressionStringLiteral::Execute(SemanticContext* context, ExpressionValue* result) const {
  result->set_string(value_);
  return true;
}

void ExpressionRequest::Dump(std::ostream& os) const { os << "request"; }

bool ExpressionRequest::Execute(SemanticContext* context, ExpressionValue* result) const {
  if (context->request() == nullptr) {
    return false;
  }
  result->set_value(nullptr, context->request());
  return true;
}

void ExpressionHandle::Dump(std::ostream& os) const { os << "handle"; }

bool ExpressionHandle::Execute(SemanticContext* context, ExpressionValue* result) const {
  result->set_handle(context->handle());
  return true;
}

void ExpressionHandleDescription::Dump(std::ostream& os) const {
  os << "HandleDescription(" << *type_ << ", " << *path_ << ')';
}

bool ExpressionHandleDescription::Execute(SemanticContext* context, ExpressionValue* result) const {
  ExpressionValue type;
  ExpressionValue path;
  if (!type_->Execute(context, &type) || !path_->Execute(context, &path)) {
    return false;
  }
  if ((type.kind() != ExpressionValue::kString) || (path.kind() != ExpressionValue::kString)) {
    return false;
  }
  result->set_inferred_handle_info(type.string(), -1, path.string(), "");
  return true;
}

void ExpressionFieldAccess::Dump(std::ostream& os) const { os << *expression_ << '.' << field_; }

bool ExpressionFieldAccess::Execute(SemanticContext* context, ExpressionValue* result) const {
  ExpressionValue value;
  if (!expression_->Execute(context, &value)) {
    return false;
  }
  if (value.kind() == ExpressionValue::kValue) {
    const StructValue* struct_value = value.value()->AsStructValue();
    if (struct_value != nullptr) {
      std::pair<const Type*, const Value*> field_value = struct_value->GetFieldValue(field_);
      if (field_value.second == nullptr) {
        return false;
      }
      const StringValue* string = field_value.second->AsStringValue();
      if (string == nullptr) {
        result->set_value(field_value.first, field_value.second);
      } else {
        result->set_string(string->string());
      }
      return true;
    }
    if (field_ == "size") {
      const StringValue* string_value = value.value()->AsStringValue();
      if (string_value != nullptr) {
        result->set_integer(string_value->string().size());
        return true;
      }
      const VectorValue* vector_value = value.value()->AsVectorValue();
      if (vector_value != nullptr) {
        result->set_integer(vector_value->values().size());
        return true;
      }
    }
  }
  return false;
}

void ExpressionSlash::Dump(std::ostream& os) const { os << *left_ << " / " << *right_; }

bool ExpressionSlash::Execute(SemanticContext* context, ExpressionValue* result) const {
  ExpressionValue left_value;
  ExpressionValue right_value;
  if (!left_->Execute(context, &left_value) || !right_->Execute(context, &right_value)) {
    return false;
  }
  const InferredHandleInfo* inferred_handle_info = nullptr;
  if (left_value.kind() == ExpressionValue::kInferredHandleInfo) {
    inferred_handle_info = left_value.inferred_handle_info();
  }
  if (left_value.kind() == ExpressionValue::kHandle) {
    inferred_handle_info =
        context->handle_semantic()->GetInferredHandleInfo(context->pid(), left_value.handle());
  }
  if (inferred_handle_info == nullptr) {
    return false;
  }
  if (right_value.kind() == ExpressionValue::kString) {
    if (inferred_handle_info->path().empty()) {
      result->set_inferred_handle_info(inferred_handle_info->type(), inferred_handle_info->fd(),
                                       right_value.string(), inferred_handle_info->attributes());
      return true;
    }
    if (right_value.string() == ".") {
      result->set_inferred_handle_info(inferred_handle_info->type(), inferred_handle_info->fd(),
                                       inferred_handle_info->path(),
                                       inferred_handle_info->attributes());
      return true;
    }
    std::string path(right_value.string());
    if (path.find("./") == 0) {
      path.erase(0, 2);
    }
    if (inferred_handle_info->path() == "/") {
      result->set_inferred_handle_info(inferred_handle_info->type(), inferred_handle_info->fd(),
                                       "/" + path, inferred_handle_info->attributes());
      return true;
    }
    result->set_inferred_handle_info(inferred_handle_info->type(), inferred_handle_info->fd(),
                                     inferred_handle_info->path() + "/" + path,
                                     inferred_handle_info->attributes());
    return true;
  }
  return false;
}

void ExpressionColon::Dump(std::ostream& os) const { os << *left_ << " : " << *right_; }

bool ExpressionColon::Execute(SemanticContext* context, ExpressionValue* result) const {
  ExpressionValue left_value;
  ExpressionValue right_value;
  if (!left_->Execute(context, &left_value) || !right_->Execute(context, &right_value)) {
    return false;
  }
  const InferredHandleInfo* inferred_handle_info = nullptr;
  if (left_value.kind() == ExpressionValue::kInferredHandleInfo) {
    inferred_handle_info = left_value.inferred_handle_info();
  }
  if (left_value.kind() == ExpressionValue::kHandle) {
    inferred_handle_info =
        context->handle_semantic()->GetInferredHandleInfo(context->pid(), left_value.handle());
  }
  if (inferred_handle_info == nullptr) {
    return false;
  }
  if (right_value.kind() == ExpressionValue::kString) {
    if (inferred_handle_info->attributes().empty()) {
      result->set_inferred_handle_info(inferred_handle_info->type(), inferred_handle_info->fd(),
                                       inferred_handle_info->path(), right_value.string());
      return true;
    }
    result->set_inferred_handle_info(
        inferred_handle_info->type(), inferred_handle_info->fd(), inferred_handle_info->path(),
        inferred_handle_info->attributes() + ", " + std::string(right_value.string()));
    return true;
  }
  return false;
}

void Assignment::Dump(std::ostream& os) const { os << *destination_ << " = " << *source_ << '\n'; }

void Assignment::Execute(AssignmentSemanticContext* context) const {
  ExpressionValue destination_value;
  ExpressionValue source_value;
  if (!destination_->Execute(context, &destination_value) ||
      !source_->Execute(context, &source_value)) {
    return;
  }
  if (destination_value.value() == nullptr) {
    return;
  }
  auto handle_value = destination_value.value()->AsHandleValue();
  if (handle_value == nullptr) {
    return;
  }
  zx_handle_t destination_handle = handle_value->handle().handle;
  if (destination_handle == ZX_HANDLE_INVALID) {
    return;
  }
  // Currently we only work on requests. If we also work on response, this would need to be
  // modified.
  switch (context->type()) {
    case ContextType::kRead:
      break;
    case ContextType::kWrite:
    case ContextType::kCall:
      destination_handle =
          context->handle_semantic()->GetLinkedHandle(context->pid(), destination_handle);
      if (destination_handle == ZX_HANDLE_INVALID) {
        return;
      }
      break;
  }
  const InferredHandleInfo* inferred_handle_info = source_value.inferred_handle_info();
  if ((inferred_handle_info == nullptr) && (source_value.handle() != ZX_HANDLE_INVALID)) {
    inferred_handle_info =
        context->handle_semantic()->GetInferredHandleInfo(context->pid(), source_value.handle());
  }
  context->handle_semantic()->CreateHandleInfo(context->timestamp(), context->tid(),
                                               destination_handle);
  context->handle_semantic()->AddInferredHandleInfo(context->pid(), destination_handle,
                                                    inferred_handle_info);
}

void MethodSemantic::Dump(std::ostream& os) const {
  for (const auto& assignment : assignments_) {
    assignment->Dump(os);
  }
}

void MethodSemantic::ExecuteAssignments(AssignmentSemanticContext* context) const {
  for (const auto& assignment : assignments_) {
    assignment->Execute(context);
  }
}

void DisplayExpression::Dump(std::ostream& os) const {
  if (!header_.empty()) {
    os << " \"" << header_ << '"';
  }
  if (expression_ != nullptr) {
    os << ' ';
    expression_->Dump(os);
  }
  if (!footer_.empty()) {
    os << " \"" << footer_ << '"';
  }
}

void DisplayExpression::PrettyPrint(PrettyPrinter& printer, SemanticContext* context) {
  if (!header_.empty()) {
    printer << header_;
  }
  if (expression_ != nullptr) {
    fidl_codec::semantic::ExpressionValue value;
    expression_->Execute(context, &value);
    value.UseLinkedHandle(context);
    value.PrettyPrint(printer);
  }
  if (!footer_.empty()) {
    printer << footer_;
  }
}

void MethodDisplay::Dump(std::ostream& os) const {
  for (const auto& input : inputs_) {
    os << "input_field:";
    input->Dump(os);
    os << ";\n";
  }
  for (const auto& result : results_) {
    os << "result:";
    result->Dump(os);
    os << ";\n";
  }
}

std::string_view InferredHandleInfo::Convert(uint32_t type) {
  switch (type) {
    case PA_PROC_SELF:
      return "proc-self";
    case PA_THREAD_SELF:
      return "thread-self";
    case PA_JOB_DEFAULT:
      return "job-default";
    case PA_VMAR_ROOT:
      return "vmar-root";
    case PA_VMAR_LOADED:
      return "initial-program-image-vmar";
    case PA_LDSVC_LOADER:
      return "ldsvc-loader";
    case PA_VMO_VDSO:
      return "vdso-vmo";
    case PA_VMO_STACK:
      return "stack-vmo";
    case PA_VMO_EXECUTABLE:
      return "executable-vmo";
    case PA_VMO_BOOTDATA:
      return "bootdata-vmo";
    case PA_VMO_BOOTFS:
      return "bootfs-vmo";
    case PA_VMO_KERNEL_FILE:
      return "kernel-file-vmo";
    case PA_NS_DIR:
      return "dir";
    case PA_FD:
      return "fd";
    case PA_DIRECTORY_REQUEST:
      return "directory-request";
    case PA_RESOURCE:
      return "resource";
    case PA_USER0:
      return "user0";
    case PA_USER1:
      return "user1";
    case PA_USER2:
      return "user2";
    default:
      return "";
  }
}

void InferredHandleInfo::Display(PrettyPrinter& printer) const {
  if (!type_.empty()) {
    printer << Green << type_ << ResetColor;
    if (fd_ != -1) {
      printer << ':' << Blue << fd_ << ResetColor;
    }
    if (!path_.empty()) {
      printer << ':' << Blue << path_ << ResetColor;
    }
    if (!attributes_.empty()) {
      printer << " [" << Blue << attributes_ << ResetColor << ']';
    }
  }
}

void ExpressionValue::UseLinkedHandle(const SemanticContext* context) {
  if (kind_ == kValue) {
    auto handle_value = value_->AsHandleValue();
    if (handle_value != nullptr) {
      set_handle(handle_value->handle().handle);
    }
  }
  if (kind_ == kHandle) {
    if (handle_ != ZX_HANDLE_INVALID) {
      zx_handle_t linked_handle =
          context->handle_semantic()->GetLinkedHandle(context->pid(), handle_);
      if (linked_handle != ZX_HANDLE_INVALID) {
        handle_ = linked_handle;
      }
    }
  }
}

void ExpressionValue::PrettyPrint(PrettyPrinter& printer) {
  switch (kind_) {
    case kUndefined:
      break;
    case kValue:
      value_->PrettyPrint(value_type_, printer);
      break;
    case kHandle: {
      zx_handle_disposition_t handle_disposition{.operation = fidl_codec::kNoHandleDisposition,
                                                 .handle = handle_,
                                                 .type = ZX_OBJ_TYPE_NONE,
                                                 .rights = ZX_RIGHT_NONE,
                                                 .result = ZX_OK};
      printer.DisplayHandle(handle_disposition);
      break;
    }
    case kInferredHandleInfo:
      inferred_handle_info_->Display(printer);
      break;
    case kString:
      printer << Red << '"' << string_ << '"' << ResetColor;
      break;
    case kInteger:
      printer << Blue << integer_ << ResetColor;
      break;
  }
}

}  // namespace semantic
}  // namespace fidl_codec
