// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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 "cobalt/dom/blob.h"

#include "base/lazy_instance.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/dom/blob_property_bag.h"
#include "cobalt/dom/dom_settings.h"

namespace cobalt {
namespace dom {

namespace {

const void* DataStart(const Blob::BlobPart& part) {
  if (part.IsType<script::Handle<script::ArrayBuffer> >()) {
    return part.AsType<script::Handle<script::ArrayBuffer> >()->Data();
  } else if (part.IsType<script::Handle<script::ArrayBufferView> >()) {
    const script::Handle<script::ArrayBufferView>& view =
        part.AsType<script::Handle<script::ArrayBufferView> >();
    return view->RawData();
  } else if (part.IsType<script::Handle<script::DataView> >()) {
    const script::Handle<script::DataView>& view =
        part.AsType<script::Handle<script::DataView> >();
    return view->RawData();
  } else if (part.IsType<scoped_refptr<Blob> >()) {
    return part.AsType<scoped_refptr<Blob> >()->data();
  }

  return NULL;
}

size_t DataLength(const Blob::BlobPart& part) {
  if (part.IsType<script::Handle<script::ArrayBuffer> >()) {
    return part.AsType<script::Handle<script::ArrayBuffer> >()->ByteLength();
  } else if (part.IsType<script::Handle<script::ArrayBufferView> >()) {
    return part.AsType<script::Handle<script::ArrayBufferView> >()
        ->ByteLength();
  } else if (part.IsType<script::Handle<script::DataView> >()) {
    return part.AsType<script::Handle<script::DataView> >()->ByteLength();
  } else if (part.IsType<scoped_refptr<Blob> >()) {
    return static_cast<size_t>(part.AsType<scoped_refptr<Blob> >()->size());
  }

  return 0;
}

size_t TotalDataLength(const script::Sequence<Blob::BlobPart>& blob_parts) {
  size_t byte_length = 0;
  for (script::Sequence<Blob::BlobPart>::size_type i = 0; i < blob_parts.size();
       i++) {
    byte_length += DataLength(blob_parts.at(i));
  }

  return byte_length;
}

base::LazyInstance<BlobPropertyBag> empty_blob_property_bag =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

Blob::Blob(script::EnvironmentSettings* settings,
           const script::Handle<script::ArrayBuffer>& buffer,
           const BlobPropertyBag& options)
    : buffer_reference_(
          this, buffer.IsEmpty()
                    ? script::ArrayBuffer::New(
                          base::polymorphic_downcast<DOMSettings*>(settings)
                              ->global_environment(),
                          0)
                    : script::ArrayBuffer::New(
                          base::polymorphic_downcast<DOMSettings*>(settings)
                              ->global_environment(),
                          buffer->Data(), buffer->ByteLength())) {
  DCHECK(settings);
  if (options.has_type()) {
    type_ = options.type();
  }
}

// TODO: Do the appropriate steps to convert the type member to lowercase ASCII
// so the media type can be exposed and used, as described in:
//    https://www.w3.org/TR/FileAPI/#constructorBlob
Blob::Blob(script::EnvironmentSettings* settings,
           const script::Sequence<BlobPart>& blob_parts,
           const BlobPropertyBag& options)
    : buffer_reference_(this,
                        script::ArrayBuffer::New(
                            base::polymorphic_downcast<DOMSettings*>(settings)
                                ->global_environment(),
                            TotalDataLength(blob_parts))),
      type_(options.type()) {
  DCHECK(settings);
  uint8* destination = static_cast<uint8*>(buffer_reference_.value().Data());
  size_t offset = 0;
  for (script::Sequence<BlobPart>::size_type i = 0; i < blob_parts.size();
       ++i) {
    const uint8* source =
        static_cast<const uint8*>(DataStart(blob_parts.at(i)));
    size_t count = DataLength(blob_parts.at(i));

    std::copy(source, source + count, destination + offset);
    offset += count;
  }
}

const BlobPropertyBag& Blob::EmptyBlobPropertyBag() {
  return empty_blob_property_bag.Get();
}

}  // namespace dom
}  // namespace cobalt
