// Copyright 2018 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/script/v8c/isolate_fellowship.h"

#include <algorithm>
#include <string>

#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "starboard/file.h"
#include "v8/include/libplatform/libplatform.h"

namespace cobalt {
namespace script {
namespace v8c {

// This file will also be touched and rebuilt every time V8 is re-built
// according to the update_snapshot_time gyp target.
const char kIsolateFellowshipBuildTime[] = __DATE__ " " __TIME__;

IsolateFellowship::IsolateFellowship() {
  TRACE_EVENT0("cobalt::script", "IsolateFellowship::IsolateFellowship");
  // TODO: Initialize V8 ICU stuff here as well.
  platform = v8::platform::CreateDefaultPlatform();
  v8::V8::InitializePlatform(platform);
  v8::V8::Initialize();
  array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();

  InitializeStartupData();
}

IsolateFellowship::~IsolateFellowship() {
  TRACE_EVENT0("cobalt::script", "IsolateFellowship::~IsolateFellowship");
  v8::V8::Dispose();
  v8::V8::ShutdownPlatform();

  DCHECK(platform);
  delete platform;
  platform = nullptr;

  DCHECK(array_buffer_allocator);
  delete array_buffer_allocator;
  array_buffer_allocator = nullptr;

  // Note that both us and V8 will have created this with new[], see
  // "snapshot-common.cc".  Also note that both startup data creation failure
  // from V8 is possible, and deleting a null pointer is safe, so there is no
  // DCHECK here.
  delete[] startup_data.data;
  startup_data = {nullptr, 0};
}

void IsolateFellowship::InitializeStartupData() {
  TRACE_EVENT0("cobalt::script", "IsolateFellowship::InitializeStartupData");
  DCHECK(startup_data.data == nullptr);

  char cache_path[SB_FILE_MAX_PATH] = {};
  if (!SbSystemGetPath(kSbSystemPathCacheDirectory, cache_path,
                       SB_ARRAY_SIZE_INT(cache_path))) {
    // If there is no cache directory, then just save the startup data in
    // memory.
    LOG(WARNING) << "Unable to read/write V8 startup snapshot data to file.";
    startup_data = v8::V8::CreateSnapshotDataBlob();
    return;
  }

  // Whether or not we should attempt to remove the existing cache file due to
  // it being in an invalid state.  We will do so in the case that it either
  // was of size 0 (but existed), or we failed to write it.
  bool should_remove_cache_file = false;

  // Attempt to read the cache file.
  std::string snapshot_file_full_path =
      std::string(cache_path) + SB_FILE_SEP_STRING +
      V8C_INTERNAL_STARTUP_DATA_CACHE_FILE_NAME;
  bool read_file = ([&]() {
    starboard::ScopedFile scoped_file(snapshot_file_full_path.c_str(),
                                      kSbFileOpenOnly | kSbFileRead);
    if (!scoped_file.IsValid()) {
      LOG(INFO) << "Can not open snapshot file";
      return false;
    }

    int64_t size = scoped_file.GetSize();
    if (size == -1) {
      LOG(ERROR) << "Received size of -1 for file that was valid.";
      return false;
    }

    if (size == 0) {
      LOG(ERROR) << "Read V8 snapshot file of size 0.";
      should_remove_cache_file = true;
      return false;
    }
    int64_t data_size = size - sizeof(kIsolateFellowshipBuildTime);

    char snapshot_time[sizeof(kIsolateFellowshipBuildTime)];
    int read =
        scoped_file.ReadAll(snapshot_time, sizeof(kIsolateFellowshipBuildTime));
    // Logically, this could be collapsed to just "read != data_size", but this
    // should be read as "if the platform explicitly told us reading failed,
    // or the platform told us we read less than we expected".
    if (read == -1 || read != sizeof(kIsolateFellowshipBuildTime)) {
      LOG(ERROR) << "Reading V8 startup snapshot time failed.";
      should_remove_cache_file = true;
      return false;
    }

    // kIsolateFellowshipBuildTime is an auto-generated/updated time stamp when
    // v8 target is compiled to update snapshot data after any v8 change.
    if (SbMemoryCompare(snapshot_time, kIsolateFellowshipBuildTime,
                        sizeof(kIsolateFellowshipBuildTime)) != 0) {
      LOG(INFO) << "V8 code was modified since last V8 startup snapshot cache "
                   "file was generated, creating a new one.";
      should_remove_cache_file = true;
      return false;
    }

    scoped_array<char> data(new char[data_size]);
    read = scoped_file.ReadAll(data.get(), data_size);
    if (read == -1 || read != data_size) {
      LOG(ERROR) << "Reading V8 startup snapshot cache file failed for some "
                    "unknown reason.";
      should_remove_cache_file = true;
      return false;
    }

    LOG(INFO) << "Successfully read V8 startup snapshot cache file.";
    startup_data.data = data.release();
    startup_data.raw_size = data_size;
    return true;
  })();

  auto maybe_remove_cache_file = [&]() {
    if (should_remove_cache_file) {
      if (!SbFileDelete(snapshot_file_full_path.c_str())) {
        LOG(ERROR) << "Failed to delete V8 startup snapshot cache file.";
      }
      should_remove_cache_file = false;
    }
  };
  maybe_remove_cache_file();

  // If we failed to read the file, then create the snapshot data and attempt
  // to write it.
  if (!read_file) {
    ([&]() {
      startup_data = v8::V8::CreateSnapshotDataBlob();
      if (startup_data.data == nullptr) {
        // Trust the V8 API, but verify.  |raw_size| should also be 0.
        DCHECK_EQ(startup_data.raw_size, 0);
        // This is technically legal w.r.t. to the API documentation, but
        // *probably* indicates a serious problem (are you hacking V8
        // internals or something?).
        LOG(WARNING) << "Failed to create V8 startup snapshot.";
        return;
      }

      starboard::ScopedFile scoped_file(snapshot_file_full_path.c_str(),
                                        kSbFileCreateOnly | kSbFileWrite);
      if (!scoped_file.IsValid()) {
        LOG(ERROR)
            << "Failed to open V8 startup snapshot cache file for writing.";
        return;
      }

      int written = scoped_file.WriteAll(kIsolateFellowshipBuildTime,
                                         sizeof(kIsolateFellowshipBuildTime));
      if (written < sizeof(kIsolateFellowshipBuildTime)) {
        LOG(ERROR) << "Failed to write V8 startup snapshot time.";
        should_remove_cache_file = true;
        return;
      }

      written = scoped_file.WriteAll(startup_data.data, startup_data.raw_size);
      if (written < startup_data.raw_size) {
        LOG(ERROR) << "Failed to write entire V8 startup snapshot.";
        should_remove_cache_file = true;
        return;
      }

      LOG(INFO) << "Successfully wrote V8 startup snapshot cache file.";
    })();
  }

  maybe_remove_cache_file();
}

}  // namespace v8c
}  // namespace script
}  // namespace cobalt
