// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/web_applications/terminal_source.h"

#include "ash/constants/ash_features.h"
#include "base/containers/flat_map.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted_memory.h"
#include "base/no_destructor.h"
#include "base/strings/escape.h"
#include "base/strings/string_util.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "chrome/browser/ash/crostini/crostini_pref_names.h"
#include "chrome/browser/ash/file_manager/path_util.h"
#include "chrome/browser/ash/file_system_provider/provided_file_system_info.h"
#include "chrome/browser/ash/file_system_provider/provider_interface.h"
#include "chrome/browser/ash/file_system_provider/service.h"
#include "chrome/browser/ash/guest_os/guest_os_terminal.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/channel_info.h"
#include "chrome/common/url_constants.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/prefs/pref_service.h"
#include "components/version_info/channel.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "net/base/mime_util.h"
#include "services/network/public/mojom/content_security_policy.mojom.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/zlib/google/compression_utils.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/webui/webui_allowlist.h"

namespace {
constexpr base::FilePath::CharType kTerminalRoot[] =
    FILE_PATH_LITERAL("/usr/share/chromeos-assets/crosh_builtin");
constexpr char kDefaultMime[] = "text/html";

class TerminalFileSystemProvider
    : public ash::file_system_provider::ExtensionProvider {
 public:
  TerminalFileSystemProvider()
      : ash::file_system_provider::ExtensionProvider(
            ProfileManager::GetPrimaryUserProfile(),
            ash::file_system_provider::ProviderId::CreateFromExtensionId(
                guest_os::kTerminalSystemAppId),
            ash::file_system_provider::Capabilities{
                .configurable = true,
                .watchable = false,
                .multiple_mounts = true,
                .source = extensions::FileSystemProviderSource::SOURCE_NETWORK},
            l10n_util::GetStringUTF8(IDS_CROSTINI_TERMINAL_APP_NAME),
            /*icon_set=*/absl::nullopt) {}
  bool RequestMount(
      Profile* profile,
      ash::file_system_provider::RequestMountCallback callback) override {
    guest_os::LaunchTerminalHome(profile, display::kInvalidDisplayId);
    content::GetUIThreadTaskRunner({})->PostTask(
        FROM_HERE, base::BindOnce(std::move(callback), base::File::FILE_OK));
    return true;
  }
};

// Attempts to read |path| as plain file.  If read fails, attempts to read
// |path|.gz and decompress. Returns true if either file is read ok.
bool ReadUncompressedOrGzip(base::FilePath path, std::string* content) {
  bool result = base::ReadFileToString(path, content);
  if (!result) {
    result =
        base::ReadFileToString(base::FilePath(path.value() + ".gz"), content);
    result = compression::GzipUncompress(*content, content);
  }
  return result;
}

void ReadFile(const base::FilePath downloads,
              const std::string& relative_path,
              content::URLDataSource::GotDataCallback callback) {
  base::FilePath path;
  std::string content;
  bool result = false;

  // If chrome://flags#terminal-dev set on dev channel, check Downloads.
  if (chrome::GetChannel() <= version_info::Channel::DEV &&
      base::FeatureList::IsEnabled(ash::features::kTerminalDev)) {
    path = downloads.Append("crosh_builtin").Append(relative_path);
    result = ReadUncompressedOrGzip(path, &content);
  }
  if (!result) {
    path = base::FilePath(kTerminalRoot).Append(relative_path);
    result = ReadUncompressedOrGzip(path, &content);
  }

  // Terminal gets files from /usr/share/chromeos-assets/crosh-builtin.
  // In chromium tests, these files don't exist, so we serve dummy values.
  if (!result) {
    static const base::NoDestructor<base::flat_map<std::string, std::string>>
        kTestFiles({
            {"html/crosh.html", ""},
            {"html/terminal.html", "<script src='/js/terminal.js'></script>"},
            {"js/terminal.js",
             "chrome.terminalPrivate.openVmshellProcess([], () => {})"},
        });
    auto it = kTestFiles->find(relative_path);
    if (it != kTestFiles->end()) {
      content = it->second;
      result = true;
    }
  }

  DCHECK(result) << path;
  std::move(callback).Run(
      base::MakeRefCounted<base::RefCountedString>(std::move(content)));
}
}  // namespace

// static
std::unique_ptr<TerminalSource> TerminalSource::ForCrosh(Profile* profile) {
  return base::WrapUnique(
      new TerminalSource(profile, chrome::kChromeUIUntrustedCroshURL, false));
}

// static
std::unique_ptr<TerminalSource> TerminalSource::ForTerminal(Profile* profile) {
  ash::file_system_provider::Service::Get(profile)->RegisterProvider(
      std::make_unique<TerminalFileSystemProvider>());
  return base::WrapUnique(new TerminalSource(
      profile, chrome::kChromeUIUntrustedTerminalURL,
      profile->GetPrefs()
          ->FindPreference(crostini::prefs::kTerminalSshAllowedByPolicy)
          ->GetValue()
          ->GetBool()));
}

TerminalSource::TerminalSource(Profile* profile,
                               std::string source,
                               bool ssh_allowed)
    : profile_(profile),
      source_(source),
      ssh_allowed_(ssh_allowed),
      downloads_(file_manager::util::GetDownloadsFolderForProfile(profile)) {
  auto* webui_allowlist = WebUIAllowlist::GetOrCreate(profile);
  const url::Origin terminal_origin = url::Origin::Create(GURL(source));
  CHECK(!terminal_origin.opaque());
  for (auto permission :
       {ContentSettingsType::CLIPBOARD_READ_WRITE, ContentSettingsType::COOKIES,
        ContentSettingsType::IMAGES, ContentSettingsType::JAVASCRIPT,
        ContentSettingsType::NOTIFICATIONS, ContentSettingsType::POPUPS,
        ContentSettingsType::SOUND}) {
    webui_allowlist->RegisterAutoGrantedPermission(terminal_origin, permission);
  }
  webui_allowlist->RegisterAutoGrantedThirdPartyCookies(
      terminal_origin, {ContentSettingsPattern::Wildcard()});
}

TerminalSource::~TerminalSource() = default;

std::string TerminalSource::GetSource() {
  return source_;
}

void TerminalSource::StartDataRequest(
    const GURL& url,
    const content::WebContents::Getter& wc_getter,
    content::URLDataSource::GotDataCallback callback) {
  // skip first '/' in path.
  std::string path = url.path().substr(1);
  if (path.empty())
    path = "html/terminal.html";

  // Refresh the $i8n{themeColor} replacement for css files.
  if (base::EndsWith(path, ".css", base::CompareCase::INSENSITIVE_ASCII)) {
    GURL contents_url;
    absl::optional<SkColor> opener_background_color;
    content::WebContents* contents = wc_getter.Run();
    if (contents) {
      contents_url = contents->GetVisibleURL();
      TabStripModel* tab_strip;
      int tab_index;
      extensions::ExtensionTabUtil::GetTabStripModel(contents, &tab_strip,
                                                     &tab_index);
      content::WebContents* opener =
          tab_strip->GetOpenerOfWebContentsAt(tab_index);
      if (opener) {
        opener_background_color = opener->GetBackgroundColor();
      }
    }
    replacements_["themeColor"] =
        base::EscapeForHTML(guest_os::GetTerminalSettingBackgroundColor(
            profile_, contents_url, opener_background_color));
  }

  base::ThreadPool::PostTask(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING},
      base::BindOnce(&ReadFile, downloads_, path, std::move(callback)));
}

std::string TerminalSource::GetMimeType(const GURL& url) {
  std::string mime_type(kDefaultMime);
  std::string ext = base::FilePath(url.path_piece()).Extension();
  if (!ext.empty())
    net::GetWellKnownMimeTypeFromExtension(ext.substr(1), &mime_type);
  return mime_type;
}

bool TerminalSource::ShouldServeMimeTypeAsContentTypeHeader() {
  // TerminalSource pages include js modules which require an explicit MimeType.
  return true;
}

const ui::TemplateReplacements* TerminalSource::GetReplacements() {
  return &replacements_;
}

std::string TerminalSource::GetContentSecurityPolicy(
    network::mojom::CSPDirectiveName directive) {
  // CSP required for SSH.
  if (ssh_allowed_) {
    switch (directive) {
      case network::mojom::CSPDirectiveName::ConnectSrc:
        return "connect-src *;";
      case network::mojom::CSPDirectiveName::FrameAncestors:
        return "frame-ancestors 'self';";
      case network::mojom::CSPDirectiveName::FrameSrc:
        return "frame-src 'self';";
      case network::mojom::CSPDirectiveName::ObjectSrc:
        return "object-src 'self';";
      case network::mojom::CSPDirectiveName::ScriptSrc:
        return "script-src 'self' 'wasm-unsafe-eval';";
      case network::mojom::CSPDirectiveName::WorkerSrc:
        return "worker-src 'self';";
      default:
        break;
    }
  }

  switch (directive) {
    case network::mojom::CSPDirectiveName::ImgSrc:
      return "img-src * data: blob:;";
    case network::mojom::CSPDirectiveName::MediaSrc:
      return "media-src data:;";
    case network::mojom::CSPDirectiveName::StyleSrc:
      return "style-src * 'unsafe-inline'; font-src *;";
    case network::mojom::CSPDirectiveName::RequireTrustedTypesFor:
      [[fallthrough]];
    case network::mojom::CSPDirectiveName::TrustedTypes:
      // TODO(crbug.com/1098685): Trusted Type remaining WebUI
      // This removes require-trusted-types-for and trusted-types directives
      // from the CSP header.
      return std::string();
    default:
      return content::URLDataSource::GetContentSecurityPolicy(directive);
  }
}

// Improve security, and it is required for wasm SharedArrayBuffer.
std::string TerminalSource::GetCrossOriginOpenerPolicy() {
  return "same-origin";
}

// Required for wasm SharedArrayBuffer.
std::string TerminalSource::GetCrossOriginEmbedderPolicy() {
  return "require-corp";
}
