/*
 * Copyright 2019 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 "fields/payload_field.h"
#include "util.h"

const std::string PayloadField::kFieldType = "PayloadField";

PayloadField::PayloadField(std::string modifier, ParseLocation loc)
    : PacketField("payload", loc), size_field_(nullptr), size_modifier_(modifier) {}

void PayloadField::SetSizeField(const SizeField* size_field) {
  if (size_field_ != nullptr) {
    ERROR(this, size_field_, size_field) << "The size field for the payload has already been assigned.";
  }

  size_field_ = size_field;
}

const std::string& PayloadField::GetFieldType() const {
  return PayloadField::kFieldType;
}

Size PayloadField::GetSize() const {
  if (size_field_ == nullptr) {
    if (!size_modifier_.empty()) {
      ERROR(this) << "Missing size field for payload with size modifier.";
    }
    return Size();
  }

  std::string dynamic_size = "(Get" + util::UnderscoreToCamelCase(size_field_->GetName()) + "() * 8)";
  if (!size_modifier_.empty()) {
    dynamic_size += "- (" + size_modifier_ + ")";
  }

  return dynamic_size;
}

std::string PayloadField::GetDataType() const {
  return "PacketView";
}

void PayloadField::GenExtractor(std::ostream&, int, bool) const {
  ERROR(this) << __func__ << " should never be called. ";
}

std::string PayloadField::GetGetterFunctionName() const {
  return "GetPayload";
}

void PayloadField::GenGetter(std::ostream& s, Size start_offset, Size end_offset) const {
  s << "PacketView<kLittleEndian> " << GetGetterFunctionName() << "() const {";
  s << "ASSERT(was_validated_);";
  s << "size_t end_index = size();";
  s << "auto to_bound = begin();";
  GenBounds(s, start_offset, end_offset, GetSize());
  s << "return GetLittleEndianSubview(field_begin, field_end);";
  s << "}\n\n";

  s << "PacketView<!kLittleEndian> " << GetGetterFunctionName() << "BigEndian() const {";
  s << "ASSERT(was_validated_);";
  s << "size_t end_index = size();";
  s << "auto to_bound = begin();";
  GenBounds(s, start_offset, end_offset, GetSize());
  s << "return GetBigEndianSubview(field_begin, field_end);";
  s << "}\n";
}

std::string PayloadField::GetBuilderParameterType() const {
  return "std::unique_ptr<BasePacketBuilder>";
}

bool PayloadField::BuilderParameterMustBeMoved() const {
  return true;
}

void PayloadField::GenBuilderParameterFromView(std::ostream& s) const {
  s << "std::make_unique<RawBuilder>(std::vector<uint8_t>(view.GetPayload().begin(), view.GetPayload().end()))";
}

bool PayloadField::HasParameterValidator() const {
  return false;
}

void PayloadField::GenParameterValidator(std::ostream&) const {
  // There is no validation needed for a payload
}

void PayloadField::GenInserter(std::ostream&) const {
  ERROR() << __func__ << " Should never be called.";
}

void PayloadField::GenValidator(std::ostream&) const {
  // Do nothing
}

void PayloadField::GenStringRepresentation(std::ostream& s, std::string) const {
  // TODO: we should parse the child packets
  s << "\"PAYLOAD[]\"";
}

std::string PayloadField::GetRustDataType() const {
  return "Vec::<u8>";
}

void PayloadField::GenRustGetter(std::ostream& s, Size start_offset, Size) const {
  s << "let " << GetName() << ": " << GetRustDataType() << " = ";
  if (size_field_ == nullptr) {
    s << "bytes[" << start_offset.bytes() << "..].into();";
  } else {
    s << "bytes[" << start_offset.bytes() << "..(";
    s << start_offset.bytes() << " + " << size_field_->GetName() << " as usize)].into();";
  }
}

void PayloadField::GenRustWriter(std::ostream&, Size, Size) const {}
