// Copyright 2017 The Cobalt Authors. 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/web/blob.h"

#include "base/lazy_instance.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/web/blob_property_bag.h"
#include "cobalt/web/context.h"
#include "cobalt/web/environment_settings.h"

namespace cobalt {
namespace web {

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();
  } else if (part.IsType<std::string>()) {
    return part.AsType<std::string>().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());
  } else if (part.IsType<std::string>()) {
    return static_cast<size_t>(part.AsType<std::string>().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>::DestructorAtExit 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<EnvironmentSettings*>(settings)
                        ->context()
                        ->global_environment(),
                    0)
              : script::ArrayBuffer::New(
                    base::polymorphic_downcast<EnvironmentSettings*>(settings)
                        ->context()
                        ->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<EnvironmentSettings*>(settings)
                        ->context()
                        ->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 web
}  // namespace cobalt
