// Copyright 2015 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 "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/message_loop/message_loop.h"
#include "build/build_config.h"
#include "mojo/application/application_runner_chromium.h"
#include "mojo/application/content_handler_factory.h"
#include "mojo/common/data_pipe_utils.h"
#include "mojo/common/message_pump_mojo.h"
#include "mojo/public/c/system/main.h"
#include "mojo/public/cpp/application/application_connection.h"
#include "mojo/public/cpp/application/application_delegate.h"
#include "mojo/public/cpp/application/application_impl.h"
#include "mojo/services/network/public/interfaces/network_service.mojom.h"
#include "mojo/services/network/public/interfaces/url_loader.mojom.h"
#include "nacl_bindings/monacl_sel_main.h"
#include "native_client/src/public/nacl_desc.h"
#include "url/gurl.h"

namespace nacl {
namespace content_handler {

namespace {
bool URLResponseToTempFile(mojo::URLResponsePtr& response,
                           base::FilePath* file_path) {
  if (!base::CreateTemporaryFile(file_path)) {
    return false;
  }

  if (!mojo::common::BlockingCopyToFile(response->body.Pass(), *file_path)) {
    base::DeleteFile(*file_path, false);
    return false;
  }

  // TODO(ncbray): can we ensure temp file deletion even if we crash?
  return true;
}

bool TempFileForURL(mojo::URLLoaderPtr& url_loader,
                    const GURL& url,
                    base::FilePath* path) {
  mojo::URLRequestPtr request(mojo::URLRequest::New());
  request->url = url.spec();
  request->method = "GET";
  request->auto_follow_redirects = true;

  // Handle the callback synchonously.
  mojo::URLResponsePtr response;
  url_loader->Start(request.Pass(), [&response](mojo::URLResponsePtr r) {
    response = r.Pass();
  });
  url_loader.WaitForIncomingMethodCall();
  if (response.is_null()) {
    LOG(FATAL) << "something went horribly wrong (missed a callback?)";
  }

  if (response->error) {
    LOG(ERROR) << "could not load " << url.spec() << " ("
               << response->error->code << ") "
               << response->error->description.get().c_str();
    return false;
  }

  return URLResponseToTempFile(response, path);
}

NaClDesc* NaClDescFromNexePath(base::FilePath& path) {
  base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ |
                            base::File::FLAG_EXECUTE);
  if (!file.IsValid()) {
    LOG(FATAL) << "failed to open " << path.value();
  }
  // Note: potentially unsafe, assumes the file is immutable. This should be
  // OK because we're currently only using temp files.
  return NaClDescCreateWithFilePathMetadata(file.TakePlatformFile(),
                                            path.AsUTF8Unsafe().c_str());
}

}  // namespace

class NaClContentHandler : public mojo::ApplicationDelegate,
                           public mojo::ContentHandlerFactory::Delegate {
 public:
  NaClContentHandler() : content_handler_factory_(this) {}

 private:
  // Overridden from ApplicationDelegate:
  void Initialize(mojo::ApplicationImpl* app) override {
    url_ = GURL(app->url());

    mojo::NetworkServicePtr network_service;
    app->ConnectToService("mojo:network_service", &network_service);

    network_service->CreateURLLoader(GetProxy(&url_loader_));
  }

  void LoadIRT(mojo::URLLoaderPtr& url_loader) {
    // TODO(ncbray): support other architectures.
    GURL irt_url;
#if defined(ARCH_CPU_X86_64)
    irt_url = url_.Resolve("irt_x64/irt_mojo.nexe");
#else
#error "Unknown / unsupported CPU architecture."
#endif
    if (!irt_url.is_valid()) {
      LOG(FATAL) << "Cannot resolve IRT URL";
    }

    if (!TempFileForURL(url_loader, irt_url, &irt_path_)) {
      LOG(FATAL) << "Could not aquire the IRT";
    }
  }

  // Overridden from ApplicationDelegate:
  bool ConfigureIncomingConnection(
      mojo::ApplicationConnection* connection) override {
    connection->AddService(&content_handler_factory_);
    return true;
  }

  // Overridden from ContentHandlerFactory::ManagedDelegate:
  void RunApplication(
      mojo::InterfaceRequest<mojo::Application> application_request,
      mojo::URLResponsePtr response) override {
    // Needed to use Mojo interfaces on this thread.
    base::MessageLoop loop(mojo::common::MessagePumpMojo::Create());

    // Aquire the nexe.
    base::FilePath nexe_path;
    if (!URLResponseToTempFile(response, &nexe_path)) {
      LOG(FATAL) << "could not redirect nexe to temp file";
    }

    // Aquire the IRT.
    mojo::URLLoaderPtr url_loader = url_loader_.Pass();
    LoadIRT(url_loader);

    // Get file handles to the IRT and nexe.
    NaClDesc* irt_desc = NaClDescFromNexePath(irt_path_);
    NaClDesc* nexe_desc = NaClDescFromNexePath(nexe_path);

    // Run.
    int exit_code = mojo::LaunchNaCl(
        nexe_desc, irt_desc, 0, NULL,
        application_request.PassMessagePipe().release().value());

    // TODO(ncbray): are the file handles actually closed at this point?

    // Clean up.
    if (!base::DeleteFile(irt_path_, false)) {
      LOG(FATAL) << "Failed to remove irt temp file " << irt_path_.value();
    }
    if (!base::DeleteFile(nexe_path, false)) {
      LOG(FATAL) << "Failed to remove nexe temp file " << nexe_path.value();
    }

    // Exits the process cleanly, does not return.
    mojo::NaClExit(exit_code);
    NOTREACHED();
  }

  mojo::ContentHandlerFactory content_handler_factory_;
  GURL url_;
  base::FilePath irt_path_;

  mojo::URLLoaderPtr url_loader_;

  DISALLOW_COPY_AND_ASSIGN(NaClContentHandler);
};

}  // namespace content_handler
}  // namespace nacl

MojoResult MojoMain(MojoHandle shell_handle) {
  mojo::ApplicationRunnerChromium runner(
      new nacl::content_handler::NaClContentHandler());
  return runner.Run(shell_handle);
}
