/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "jdwp/jdwp.h"

#include <inttypes.h>

#include "android-base/stringprintf.h"

#include "jdwp/jdwp_priv.h"

namespace art {

namespace JDWP {

Request::Request(const uint8_t* bytes, uint32_t available) : p_(bytes) {
  byte_count_ = Read4BE();
  end_ =  bytes + byte_count_;
  CHECK_LE(byte_count_, available);

  id_ = Read4BE();
  int8_t flags = Read1();
  if ((flags & kJDWPFlagReply) != 0) {
    LOG(FATAL) << "reply?!";
  }

  command_set_ = Read1();
  command_ = Read1();
}

Request::~Request() {
}

void Request::CheckConsumed() {
  if (p_ < end_) {
    CHECK(p_ == end_) << "read too few bytes: " << (end_ - p_);
  } else if (p_ > end_) {
    CHECK(p_ == end_) << "read too many bytes: " << (p_ - end_);
  }
}

std::string Request::ReadUtf8String() {
  uint32_t length = Read4BE();
  std::string s;
  s.resize(length);
  memcpy(&s[0], p_, length);
  p_ += length;
  VLOG(jdwp) << "    string \"" << s << "\"";
  return s;
}

// Helper function: read a variable-width value from the input buffer.
uint64_t Request::ReadValue(size_t width) {
  uint64_t value = -1;
  switch (width) {
    case 1: value = Read1(); break;
    case 2: value = Read2BE(); break;
    case 4: value = Read4BE(); break;
    case 8: value = Read8BE(); break;
    default: LOG(FATAL) << width;
  }
  return value;
}

int32_t Request::ReadSigned32(const char* what) {
  int32_t value = static_cast<int32_t>(Read4BE());
  VLOG(jdwp) << "    " << what << " " << value;
  return value;
}

uint32_t Request::ReadUnsigned32(const char* what) {
  uint32_t value = Read4BE();
  VLOG(jdwp) << "    " << what << " " << value;
  return value;
}

FieldId Request::ReadFieldId() {
  FieldId id = Read8BE();
  VLOG(jdwp) << "    field id " << DescribeField(id);
  return id;
}

MethodId Request::ReadMethodId() {
  MethodId id = Read8BE();
  VLOG(jdwp) << "    method id " << DescribeMethod(id);
  return id;
}

ObjectId Request::ReadObjectId(const char* specific_kind) {
  ObjectId id = Read8BE();
  VLOG(jdwp) << android::base::StringPrintf("    %s id %#" PRIx64, specific_kind, id);
  return id;
}

ObjectId Request::ReadArrayId() {
  return ReadObjectId("array");
}

ObjectId Request::ReadObjectId() {
  return ReadObjectId("object");
}

ObjectId Request::ReadThreadId() {
  return ReadObjectId("thread");
}

ObjectId Request::ReadThreadGroupId() {
  return ReadObjectId("thread group");
}

RefTypeId Request::ReadRefTypeId() {
  RefTypeId id = Read8BE();
  VLOG(jdwp) << "    ref type id " << DescribeRefTypeId(id);
  return id;
}

FrameId Request::ReadFrameId() {
  FrameId id = Read8BE();
  VLOG(jdwp) << "    frame id " << id;
  return id;
}

JdwpTag Request::ReadTag() {
  return ReadEnum1<JdwpTag>("tag");
}

JdwpTypeTag Request::ReadTypeTag() {
  return ReadEnum1<JdwpTypeTag>("type tag");
}

JdwpLocation Request::ReadLocation() {
  JdwpLocation location;
  memset(&location, 0, sizeof(location));  // Allows memcmp(3) later.
  location.type_tag = ReadTypeTag();
  location.class_id = ReadObjectId("class");
  location.method_id = ReadMethodId();
  location.dex_pc = Read8BE();
  VLOG(jdwp) << "    location " << location;
  return location;
}

JdwpModKind Request::ReadModKind() {
  return ReadEnum1<JdwpModKind>("mod kind");
}

uint8_t Request::Read1() {
  return *p_++;
}

uint16_t Request::Read2BE() {
  uint16_t result = p_[0] << 8 | p_[1];
  p_ += 2;
  return result;
}

uint32_t Request::Read4BE() {
  uint32_t result = p_[0] << 24;
  result |= p_[1] << 16;
  result |= p_[2] << 8;
  result |= p_[3];
  p_ += 4;
  return result;
}

uint64_t Request::Read8BE() {
  uint64_t high = Read4BE();
  uint64_t low = Read4BE();
  return (high << 32) | low;
}

}  // namespace JDWP

}  // namespace art
