// Copyright 2015 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/loader/fetcher_factory.h"

#include <memory>
#include <sstream>
#include <string>

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "cobalt/loader/about_fetcher.h"
#include "cobalt/loader/blob_fetcher.h"
#include "cobalt/loader/cache_fetcher.h"
#include "cobalt/loader/embedded_fetcher.h"
#include "cobalt/loader/error_fetcher.h"
#include "cobalt/loader/file_fetcher.h"
#include "cobalt/loader/net_fetcher.h"
#include "cobalt/network/network_module.h"

namespace cobalt {
namespace loader {
namespace {

#if defined(ENABLE_ABOUT_SCHEME)
const char kAboutScheme[] = "about";
#endif

bool FileURLToFilePath(const GURL& url, base::FilePath* file_path) {
  DCHECK(url.is_valid() && url.SchemeIsFile());
  std::string path = url.path();
  DCHECK_EQ('/', path[0]);
  path.erase(0, 1);
  *file_path = base::FilePath(path);
  return !file_path->empty();
}

std::string ClipUrl(const GURL& url, size_t length) {
  const std::string& spec = url.possibly_invalid_spec();
  if (spec.size() < length) {
    return spec;
  }

  size_t remain = length - 5;
  size_t head = remain / 2;
  size_t tail = remain - head;

  return spec.substr(0, head) + "[...]" + spec.substr(spec.size() - tail);
}

}  // namespace

FetcherFactory::FetcherFactory(network::NetworkModule* network_module)
    : file_thread_("File"),
      network_module_(network_module),
      read_cache_callback_() {
  file_thread_.Start();
}

FetcherFactory::FetcherFactory(network::NetworkModule* network_module,
                               const base::FilePath& extra_search_dir)
    : file_thread_("File"),
      network_module_(network_module),
      extra_search_dir_(extra_search_dir),
      read_cache_callback_() {
  file_thread_.Start();
}

FetcherFactory::FetcherFactory(
    network::NetworkModule* network_module,
    const base::FilePath& extra_search_dir,
    const BlobFetcher::ResolverCallback& blob_resolver,
    const base::Callback<int(const std::string&, std::unique_ptr<char[]>*)>&
        read_cache_callback)
    : file_thread_("File"),
      network_module_(network_module),
      extra_search_dir_(extra_search_dir),
      blob_resolver_(blob_resolver),
      read_cache_callback_(read_cache_callback) {
  file_thread_.Start();
}

std::unique_ptr<Fetcher> FetcherFactory::CreateFetcher(
    const GURL& url, Fetcher::Handler* handler) {
  return CreateSecureFetcher(url, csp::SecurityCallback(), kNoCORSMode,
                             Origin(), handler);
}

std::unique_ptr<Fetcher> FetcherFactory::CreateSecureFetcher(
    const GURL& url, const csp::SecurityCallback& url_security_callback,
    RequestMode request_mode, const Origin& origin, Fetcher::Handler* handler) {
  LOG(INFO) << "Fetching: " << ClipUrl(url, 200);

  if (!url.is_valid()) {
    std::stringstream error_message;
    error_message << "URL is invalid: " << url;
    return std::unique_ptr<Fetcher>(
        new ErrorFetcher(handler, error_message.str()));
  }

  if ((url.SchemeIs("https") || url.SchemeIs("http") || url.SchemeIs("data")) &&
      network_module_) {
    NetFetcher::Options options;
    return std::unique_ptr<Fetcher>(
        new NetFetcher(url, url_security_callback, handler, network_module_,
                       options, request_mode, origin));
  }

  if (url.SchemeIs("blob") && !blob_resolver_.is_null()) {
    return std::unique_ptr<Fetcher>(
        new BlobFetcher(url, handler, blob_resolver_));
  }

  if (url.SchemeIs(kEmbeddedScheme)) {
    EmbeddedFetcher::Options options;
    return std::unique_ptr<Fetcher>(
        new EmbeddedFetcher(url, url_security_callback, handler, options));
  }

  // h5vcc-cache: scheme requires read_cache_callback_ which is not available
  // in the main WebModule.
  if (url.SchemeIs(kCacheScheme) && !read_cache_callback_.is_null()) {
    return std::unique_ptr<Fetcher>(new CacheFetcher(
        url, url_security_callback, handler, read_cache_callback_));
  }

  if (url.SchemeIsFile()) {
    base::FilePath file_path;
    if (!FileURLToFilePath(url, &file_path)) {
      std::stringstream error_message;
      error_message << "File URL cannot be converted to file path: " << url;
      return std::unique_ptr<Fetcher>(
          new ErrorFetcher(handler, error_message.str()));
    }

    FileFetcher::Options options;
    options.message_loop_proxy = file_thread_.task_runner();
    options.extra_search_dir = extra_search_dir_;
    return std::unique_ptr<Fetcher>(
        new FileFetcher(file_path, handler, options));
  }

#if defined(ENABLE_ABOUT_SCHEME)
  if (url.SchemeIs(kAboutScheme)) {
    return std::unique_ptr<Fetcher>(new AboutFetcher(handler));
  }
#endif

  std::stringstream error_message;
  error_message << "Scheme " << url.scheme() << ": is not supported";
  return std::unique_ptr<Fetcher>(
      new ErrorFetcher(handler, error_message.str()));
}

}  // namespace loader
}  // namespace cobalt
