// Copyright 2019 The Chromium 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 "third_party/blink/renderer/modules/nfc/ndef_message.h"

#include "services/device/public/mojom/nfc.mojom-blink.h"
#include "third_party/blink/renderer/bindings/modules/v8/string_or_array_buffer_or_array_buffer_view_or_ndef_message_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_ndef_message_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_ndef_record_init.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/nfc/ndef_record.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"

namespace blink {

// static
NDEFMessage* NDEFMessage::Create(const ExecutionContext* execution_context,
                                 const NDEFMessageInit* init,
                                 ExceptionState& exception_state,
                                 bool is_embedded) {
  // https://w3c.github.io/web-nfc/#creating-ndef-message

  // NDEFMessageInit#records is a required field.
  DCHECK(init->hasRecords());
  if (init->records().IsEmpty()) {
    exception_state.ThrowTypeError(
        "NDEFMessageInit#records being empty makes no sense.");
    return nullptr;
  }

  NDEFMessage* message = MakeGarbageCollected<NDEFMessage>();
  for (const NDEFRecordInit* record_init : init->records()) {
    NDEFRecord* record = NDEFRecord::Create(execution_context, record_init,
                                            exception_state, is_embedded);
    if (exception_state.HadException())
      return nullptr;
    DCHECK(record);
    message->records_.push_back(record);
  }
  return message;
}

// static
NDEFMessage* NDEFMessage::Create(const ExecutionContext* execution_context,
                                 const NDEFMessageSource& source,
                                 ExceptionState& exception_state) {
  // https://w3c.github.io/web-nfc/#creating-ndef-message
  if (source.IsString()) {
    NDEFMessage* message = MakeGarbageCollected<NDEFMessage>();
    message->records_.push_back(MakeGarbageCollected<NDEFRecord>(
        execution_context, source.GetAsString()));
    return message;
  }

  if (source.IsArrayBuffer()) {
    WTF::Vector<uint8_t> payload_data;
    size_t byte_length = source.GetAsArrayBuffer()->ByteLength();
    if (byte_length > std::numeric_limits<wtf_size_t>::max()) {
      exception_state.ThrowRangeError(
          "Buffer size exceeds maximum heap object size.");
      return nullptr;
    }
    payload_data.Append(
        static_cast<uint8_t*>(source.GetAsArrayBuffer()->Data()),
        static_cast<wtf_size_t>(byte_length));
    NDEFMessage* message = MakeGarbageCollected<NDEFMessage>();
    message->records_.push_back(MakeGarbageCollected<NDEFRecord>(
        String() /* id */, "application/octet-stream",
        std::move(payload_data)));
    return message;
  }

  if (source.IsArrayBufferView()) {
    size_t byte_length = source.GetAsArrayBufferView()->byteLength();
    if (byte_length > std::numeric_limits<wtf_size_t>::max()) {
      exception_state.ThrowRangeError(
          "Buffer size exceeds maximum heap object size.");
      return nullptr;
    }
    WTF::Vector<uint8_t> payload_data;
    payload_data.Append(
        static_cast<uint8_t*>(source.GetAsArrayBufferView()->BaseAddress()),
        static_cast<wtf_size_t>(byte_length));
    NDEFMessage* message = MakeGarbageCollected<NDEFMessage>();
    message->records_.push_back(MakeGarbageCollected<NDEFRecord>(
        String() /* id */, "application/octet-stream",
        std::move(payload_data)));
    return message;
  }

  if (source.IsNDEFMessageInit()) {
    return Create(execution_context, source.GetAsNDEFMessageInit(),
                  exception_state);
  }

  NOTREACHED();
  return nullptr;
}

// static
NDEFMessage* NDEFMessage::CreateAsPayloadOfSmartPoster(
    const ExecutionContext* execution_context,
    const NDEFMessageInit* init,
    ExceptionState& exception_state) {
  // NDEFMessageInit#records is a required field.
  DCHECK(init->hasRecords());

  NDEFMessage* payload_message = MakeGarbageCollected<NDEFMessage>();

  bool has_url_record = false;
  bool has_size_record = false;
  bool has_type_record = false;
  bool has_action_record = false;
  for (const NDEFRecordInit* record_init : init->records()) {
    const String& record_type = record_init->recordType();
    if (record_type == "url") {
      // The single mandatory url record.
      if (has_url_record) {
        exception_state.ThrowTypeError(
            "'smart-poster' NDEFRecord contains more than one url record.");
        return nullptr;
      }
      has_url_record = true;
    } else if (record_type == ":s") {
      // Zero or one size record.
      if (has_size_record) {
        exception_state.ThrowTypeError(
            "'smart-poster' NDEFRecord contains more than one size record.");
        return nullptr;
      }
      has_size_record = true;
    } else if (record_type == ":t") {
      // Zero or one type record.
      if (has_type_record) {
        exception_state.ThrowTypeError(
            "'smart-poster' NDEFRecord contains more than one type record.");
        return nullptr;
      }
      has_type_record = true;
    } else if (record_type == ":act") {
      // Zero or one action record.
      if (has_action_record) {
        exception_state.ThrowTypeError(
            "'smart-poster' NDEFRecord contains more than one action record.");
        return nullptr;
      }
      has_action_record = true;
    } else {
      // No restriction on other record types.
    }
    NDEFRecord* record = NDEFRecord::Create(
        execution_context, record_init, exception_state, /*is_embedded=*/true);
    if (exception_state.HadException())
      return nullptr;
    DCHECK(record);

    if (record->recordType() == ":s" && record->payloadData().size() != 4) {
      exception_state.ThrowTypeError(
          "Size record of smart-poster must contain a 4-byte 32 bit unsigned "
          "integer.");
      return nullptr;
    }
    if (record->recordType() == ":act" && record->payloadData().size() != 1) {
      exception_state.ThrowTypeError(
          "Action record of smart-poster must contain only a single byte.");
      return nullptr;
    }

    payload_message->records_.push_back(record);
  }

  if (!has_url_record) {
    exception_state.ThrowTypeError(
        "'smart-poster' NDEFRecord is missing the single mandatory url "
        "record.");
    return nullptr;
  }

  return payload_message;
}

NDEFMessage::NDEFMessage() = default;

NDEFMessage::NDEFMessage(const device::mojom::blink::NDEFMessage& message) {
  for (wtf_size_t i = 0; i < message.data.size(); ++i) {
    records_.push_back(MakeGarbageCollected<NDEFRecord>(*message.data[i]));
  }
}

const HeapVector<Member<NDEFRecord>>& NDEFMessage::records() const {
  return records_;
}

void NDEFMessage::Trace(Visitor* visitor) const {
  visitor->Trace(records_);
  ScriptWrappable::Trace(visitor);
}

}  // namespace blink
