// 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/web_applications/web_app.h"

#include <memory>
#include <string>
#include <string_view>

#include "base/base64.h"
#include "base/check.h"
#include "base/command_line.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_integrity_block_data.h"
#include "chrome/browser/web_applications/test/fake_web_app_provider.h"
#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
#include "chrome/browser/web_applications/test/web_app_test.h"
#include "chrome/browser/web_applications/test/web_app_test_utils.h"
#include "chrome/browser/web_applications/web_app_constants.h"
#include "chrome/browser/web_applications/web_app_helpers.h"
#include "chrome/browser/web_applications/web_app_install_info.h"
#include "chrome/browser/web_applications/web_app_management_type.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_utils.h"
#include "chrome/common/chrome_paths.h"
#include "components/web_package/signed_web_bundles/ecdsa_p256_public_key.h"
#include "components/web_package/signed_web_bundles/ecdsa_p256_sha256_signature.h"
#include "components/web_package/signed_web_bundles/signed_web_bundle_signature_stack_entry.h"
#include "components/webapps/isolated_web_apps/types/storage_location.h"
#include "components/webapps/isolated_web_apps/types/update_channel.h"
#include "services/network/public/cpp/permissions_policy/origin_with_possible_wildcards.h"
#include "services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace web_app {

namespace {

constexpr std::string_view kGenerateExpectationsMessage = R"(
In order to regenerate expectations run
the following command:
  out/<dir>/unit_tests \
    --gtest_filter="WebAppTest.*" \
    --rebaseline-web-app-expectations
)";

base::Value WebAppToPlatformAgnosticDebugValue(
    std::unique_ptr<WebApp> web_app) {
  return web_app->AsDebugValueWithOnlyPlatformAgnosticFields();
}

base::FilePath GetTestDataDir() {
  base::FilePath test_data_dir;
  CHECK(base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
  return test_data_dir;
}

base::FilePath GetPathRelativeToTestDataDir(
    const base::FilePath absolute_path) {
  base::FilePath relative_path;
  GetTestDataDir().AppendRelativePath(absolute_path, &relative_path);
  return relative_path;
}

base::FilePath GetPathToTestFile(std::string_view filename) {
  return GetTestDataDir().AppendASCII("web_apps").AppendASCII(filename);
}

std::string GetContentsOrDie(const base::FilePath& filepath) {
  std::string contents;
  CHECK(base::ReadFileToString(filepath, &contents));
  return contents;
}

void SetContentsOrDie(const base::FilePath& filepath,
                      std::string_view contents) {
  CHECK(base::WriteFile(filepath, contents));
}

std::string SerializeValueToJsonOrDie(const base::Value& value) {
  std::string contents;
  CHECK(base::JSONWriter::WriteWithOptions(
      value, base::JSONWriter::OPTIONS_PRETTY_PRINT, &contents));
  return contents;
}

base::Value DeserializeValueFromJsonOrDie(std::string_view json) {
  std::optional<base::Value> value = base::JSONReader::Read(json);
  CHECK(value.has_value());
  return *std::move(value);
}

bool IsRebaseline() {
  const base::CommandLine& command_line =
      *base::CommandLine::ForCurrentProcess();
  return command_line.HasSwitch("rebaseline-web-app-expectations");
}

void SaveExpectationsContentsOrDie(const base::FilePath path,
                                   std::string_view contents) {
  const std::string current_contents = GetContentsOrDie(path);

  const base::FilePath test_data_dir_relative_path =
      GetPathRelativeToTestDataDir(path);

  if (current_contents != contents) {
    LOG(INFO) << "New content is generated for " << test_data_dir_relative_path;
  } else {
    LOG(INFO) << "No new content is generated for "
              << test_data_dir_relative_path;
  }

  SetContentsOrDie(path, contents);
}

static constexpr char kEcdsaP256PublicKeyBase64[] =
    "AxyCBzvQfu1yaF01392k1gu2qCtT1uA2+WfIEhlyJB5S";
static constexpr char kEcdsaP256SHA256SignatureHex[] =
    "3044022007381524F538B04F99CCC62703F06C87F66EF41BDA18A22D8E57952AA23E53A6"
    "022063C7F81D3A44798CB95823FA38FC23B15E0483744657FF49E1E83AB8C06B63C2";

IsolatedWebAppIntegrityBlockData CreateIntegrityBlockData() {
  std::vector<web_package::SignedWebBundleSignatureInfo> signatures;

  // EcdsaP256SHA256:
  {
    auto public_key = *web_package::EcdsaP256PublicKey::Create(
        *base::Base64Decode(kEcdsaP256PublicKeyBase64));
    std::vector<uint8_t> data;
    CHECK(base::HexStringToBytes(kEcdsaP256SHA256SignatureHex, &data));
    auto signature = *web_package::EcdsaP256SHA256Signature::Create(data);
    signatures.push_back(
        web_package::SignedWebBundleSignatureInfoEcdsaP256SHA256(
            std::move(public_key), std::move(signature)));
  }

  return IsolatedWebAppIntegrityBlockData(std::move(signatures));
}

}  // namespace

TEST(WebAppTest, HasAnySources) {
  WebApp app{GenerateAppId(/*manifest_id_path=*/std::nullopt,
                           GURL("https://example.com"))};

  EXPECT_FALSE(app.HasAnySources());
  for (WebAppManagement::Type source : WebAppManagementTypes::All()) {
    app.AddSource(source);
    EXPECT_TRUE(app.HasAnySources());
  }

  for (WebAppManagement::Type source : WebAppManagementTypes::All()) {
    EXPECT_TRUE(app.HasAnySources());
    app.RemoveSource(source);
  }
  EXPECT_FALSE(app.HasAnySources());
}

TEST(WebAppTest, HasOnlySource) {
  WebApp app{GenerateAppId(/*manifest_id_path=*/std::nullopt,
                           GURL("https://example.com"))};

  for (WebAppManagement::Type source : WebAppManagementTypes::All()) {
    app.AddSource(source);
    EXPECT_TRUE(app.HasOnlySource(source));

    app.RemoveSource(source);
    EXPECT_FALSE(app.HasOnlySource(source));
  }

  app.AddSource(WebAppManagement::kMinValue);
  EXPECT_TRUE(app.HasOnlySource(WebAppManagement::kMinValue));

  for (WebAppManagement::Type source : WebAppManagementTypes::All()) {
    if (source == WebAppManagement::kMinValue) {
      continue;
    }
    app.AddSource(source);
    EXPECT_FALSE(app.HasOnlySource(source));
    EXPECT_FALSE(app.HasOnlySource(WebAppManagement::kMinValue));
  }

  for (WebAppManagement::Type source : WebAppManagementTypes::All()) {
    if (source == WebAppManagement::kMinValue) {
      continue;
    }
    EXPECT_FALSE(app.HasOnlySource(WebAppManagement::kMinValue));
    app.RemoveSource(source);
    EXPECT_FALSE(app.HasOnlySource(source));
  }

  EXPECT_TRUE(app.HasOnlySource(WebAppManagement::kMinValue));
  app.RemoveSource(WebAppManagement::kMinValue);
  EXPECT_FALSE(app.HasOnlySource(WebAppManagement::kMinValue));
  EXPECT_FALSE(app.HasAnySources());
}

TEST(WebAppTest, WasInstalledByUser) {
  WebApp app{GenerateAppId(/*manifest_id_path=*/std::nullopt,
                           GURL("https://example.com"))};

  app.AddSource(WebAppManagement::kSync);
  EXPECT_TRUE(app.WasInstalledByUser());

  app.AddSource(WebAppManagement::kWebAppStore);
  EXPECT_TRUE(app.WasInstalledByUser());

  app.RemoveSource(WebAppManagement::kSync);
  EXPECT_TRUE(app.WasInstalledByUser());

  app.RemoveSource(WebAppManagement::kWebAppStore);
  EXPECT_FALSE(app.WasInstalledByUser());

  app.AddSource(WebAppManagement::kOneDriveIntegration);
  EXPECT_TRUE(app.WasInstalledByUser());

  app.RemoveSource(WebAppManagement::kOneDriveIntegration);
  EXPECT_FALSE(app.WasInstalledByUser());

  app.AddSource(WebAppManagement::kDefault);
  EXPECT_FALSE(app.WasInstalledByUser());

  app.AddSource(WebAppManagement::kSystem);
  EXPECT_FALSE(app.WasInstalledByUser());

  app.AddSource(WebAppManagement::kKiosk);
  EXPECT_FALSE(app.WasInstalledByUser());

  app.AddSource(WebAppManagement::kPolicy);
  EXPECT_FALSE(app.WasInstalledByUser());

  app.AddSource(WebAppManagement::kSubApp);
  EXPECT_FALSE(app.WasInstalledByUser());

  app.RemoveSource(WebAppManagement::kDefault);
  EXPECT_FALSE(app.WasInstalledByUser());

  app.RemoveSource(WebAppManagement::kSystem);
  EXPECT_FALSE(app.WasInstalledByUser());

  app.RemoveSource(WebAppManagement::kKiosk);
  EXPECT_FALSE(app.WasInstalledByUser());

  app.RemoveSource(WebAppManagement::kPolicy);
  EXPECT_FALSE(app.WasInstalledByUser());

  app.RemoveSource(WebAppManagement::kSubApp);
  EXPECT_FALSE(app.WasInstalledByUser());
}

TEST(WebAppTest, CanUserUninstallWebApp) {
  WebApp app{GenerateAppId(/*manifest_id_path=*/std::nullopt,
                           GURL("https://example.com"))};

  app.AddSource(WebAppManagement::kDefault);
  EXPECT_TRUE(app.IsPreinstalledApp());
  EXPECT_TRUE(app.CanUserUninstallWebApp());

  app.AddSource(WebAppManagement::kSync);
  EXPECT_TRUE(app.CanUserUninstallWebApp());
  app.AddSource(WebAppManagement::kWebAppStore);
  EXPECT_TRUE(app.CanUserUninstallWebApp());
  app.AddSource(WebAppManagement::kSubApp);
  EXPECT_TRUE(app.CanUserUninstallWebApp());
  app.AddSource(WebAppManagement::kOneDriveIntegration);
  EXPECT_TRUE(app.CanUserUninstallWebApp());

  app.AddSource(WebAppManagement::kPolicy);
  EXPECT_FALSE(app.CanUserUninstallWebApp());
  app.AddSource(WebAppManagement::kKiosk);
  EXPECT_FALSE(app.CanUserUninstallWebApp());
  app.AddSource(WebAppManagement::kSystem);
  EXPECT_FALSE(app.CanUserUninstallWebApp());

  app.RemoveSource(WebAppManagement::kSync);
  EXPECT_FALSE(app.CanUserUninstallWebApp());
  app.RemoveSource(WebAppManagement::kWebAppStore);
  EXPECT_FALSE(app.CanUserUninstallWebApp());
  app.RemoveSource(WebAppManagement::kSubApp);
  EXPECT_FALSE(app.CanUserUninstallWebApp());

  app.RemoveSource(WebAppManagement::kSystem);
  EXPECT_FALSE(app.CanUserUninstallWebApp());

  app.RemoveSource(WebAppManagement::kKiosk);
  EXPECT_FALSE(app.CanUserUninstallWebApp());

  app.RemoveSource(WebAppManagement::kPolicy);
  EXPECT_TRUE(app.CanUserUninstallWebApp());

  app.RemoveSource(WebAppManagement::kOneDriveIntegration);
  EXPECT_TRUE(app.CanUserUninstallWebApp());

  EXPECT_TRUE(app.IsPreinstalledApp());
  app.RemoveSource(WebAppManagement::kDefault);
  EXPECT_FALSE(app.IsPreinstalledApp());
}

TEST(WebAppTest, EmptyAppAsDebugValue) {
  const base::FilePath path_to_test_file =
      GetPathToTestFile("empty_web_app.json");
  const base::Value web_app_debug_value =
      WebAppToPlatformAgnosticDebugValue(std::make_unique<WebApp>("empty_app"));

  if (IsRebaseline()) {
    LOG(INFO) << "Generating expectations empty web app unit test in "
              << GetPathRelativeToTestDataDir(path_to_test_file);
    SaveExpectationsContentsOrDie(
        path_to_test_file, SerializeValueToJsonOrDie(web_app_debug_value));
    return;
  }

  EXPECT_EQ(DeserializeValueFromJsonOrDie(GetContentsOrDie(path_to_test_file)),
            web_app_debug_value)
      << "Debug value of empty web app is unexpected. "
      << kGenerateExpectationsMessage;
}

// The values of the SampleApp are randomly generated. This test is mainly
// checking that the output is formatted well and doesn't crash. Exact field
// values are unimportant.
//
// If you have made changes and this test is failing, run the test with
// `--rebaseline-web-app-expectations` to generate a new `sample_web_app.json`.
TEST(WebAppTest, SampleAppAsDebugValue) {
  const base::FilePath path_to_test_file =
      GetPathToTestFile("sample_web_app.json");
  const base::Value web_app_debug_value = WebAppToPlatformAgnosticDebugValue(
      test::CreateRandomWebApp({.seed = 1234, .non_zero = true}));

  if (IsRebaseline()) {
    LOG(INFO) << "Generating expectations sample web app unit test in "
              << GetPathRelativeToTestDataDir(path_to_test_file);
    SaveExpectationsContentsOrDie(
        path_to_test_file, SerializeValueToJsonOrDie(web_app_debug_value));
    return;
  }

  EXPECT_EQ(DeserializeValueFromJsonOrDie(GetContentsOrDie(path_to_test_file)),
            web_app_debug_value)
      << "Debug value of sample web app is unexpected. "
      << kGenerateExpectationsMessage;
}

TEST(WebAppTest, RandomAppAsDebugValue_NoCrash) {
  for (uint32_t seed = 0; seed < 1000; ++seed) {
    const base::Value web_app_debug_value =
        test::CreateRandomWebApp({.seed = seed})->AsDebugValue();

    EXPECT_TRUE(web_app_debug_value.is_dict());
    EXPECT_TRUE(base::ToString(web_app_debug_value).length() > 10);
  }
}

TEST(WebAppTest, IsolationDataStartsEmpty) {
  WebApp app{GenerateAppId(/*manifest_id_path=*/std::nullopt,
                           GURL("https://example.com"))};

  EXPECT_FALSE(app.isolation_data().has_value());
}

TEST(WebAppTest, IsolationDataDebugValue) {
  GURL kStartUrl("isolated-app://random_name");
  WebApp app(GenerateManifestIdFromStartUrlOnly(kStartUrl),
             /*start_url=*/kStartUrl, /*scope=*/kStartUrl);
  app.SetIsolationData(
      IsolationData::Builder(
          IwaStorageOwnedBundle{"random_name", /*dev_mode=*/false},
          *IwaVersion::Create("1.0.0"))
          .Build());

  EXPECT_TRUE(app.isolation_data().has_value());

  base::Value expected_isolation_data = base::JSONReader::Read(R"|({
        "isolated_web_app_location": {
          "owned_bundle": {
            "dev_mode": false,
            "dir_name_ascii": "random_name"
          }
        },
        "version": "1.0.0",
        "controlled_frame_partitions (on-disk)": [],
        "opened_tabs_counter_notification_state": null,
        "pending_update_info": null,
        "integrity_block_data": null
      })|")
                                            .value();

  base::Value::Dict debug_app = app.AsDebugValue().GetDict().Clone();
  base::Value::Dict* debug_isolation_data =
      debug_app.FindDict("isolation_data");
  EXPECT_TRUE(debug_isolation_data != nullptr);
  EXPECT_EQ(*debug_isolation_data, expected_isolation_data);
}

TEST(WebAppTest, IsolationDataPendingUpdateInfoDebugValue) {
  GURL kStartUrl("isolated-app://random_name");
  WebApp app(GenerateManifestIdFromStartUrlOnly(kStartUrl),
             /*start_url=*/kStartUrl, /*scope=*/kStartUrl);

  static constexpr std::string_view kUpdateManifestUrl =
      "https://update-manifest.com";
  static const UpdateChannel kUpdateChannel = UpdateChannel::default_channel();

  auto integrity_block_data = CreateIntegrityBlockData();
  app.SetIsolationData(
      IsolationData::Builder(
          IwaStorageOwnedBundle{"random_name", /*dev_mode=*/true},
          *IwaVersion::Create("1.0.0"))
          .SetPendingUpdateInfo(IsolationData::PendingUpdateInfo(
              IwaStorageUnownedBundle{
                  base::FilePath(FILE_PATH_LITERAL("random_folder"))},
              *IwaVersion::Create("2.0.0"), integrity_block_data))
          .SetIntegrityBlockData(integrity_block_data)
          .SetUpdateManifestUrl(GURL(kUpdateManifestUrl))
          .SetUpdateChannel(kUpdateChannel)
          .Build());

  EXPECT_TRUE(app.isolation_data().has_value());

  auto ib_data_serialized = *base::WriteJson(base::Value::Dict().Set(
      "signatures", base::Value::List().Append(base::Value::Dict().Set(
                        "ecdsa_p256_sha256",
                        base::Value::Dict()
                            .Set("public_key", kEcdsaP256PublicKeyBase64)
                            .Set("signature", kEcdsaP256SHA256SignatureHex)))));

  static constexpr std::string_view kExpectedIsolationDataFormat =
      R"|({
        "isolated_web_app_location": {
          "owned_bundle": {
            "dev_mode": true,
            "dir_name_ascii": "random_name"
          }
        },
        "version": "1.0.0",
        "controlled_frame_partitions (on-disk)": [],
        "opened_tabs_counter_notification_state": null,
        "pending_update_info": {
          "isolated_web_app_location": {
            "unowned_bundle": {
              "path": "random_folder"
            }
          },
          "version": "2.0.0",
          "integrity_block_data": $1
        },
        "integrity_block_data": $2,
        "update_manifest_url": "$3",
        "update_channel": "$4"
      })|";

  base::Value expected_isolation_data =
      *base::JSONReader::Read(base::ReplaceStringPlaceholders(
          kExpectedIsolationDataFormat,
          {ib_data_serialized, ib_data_serialized,
           GURL(kUpdateManifestUrl).spec(), kUpdateChannel.ToString()},
          /*offsets=*/nullptr));

  base::Value::Dict debug_app = app.AsDebugValue().GetDict().Clone();
  base::Value::Dict* debug_isolation_data =
      debug_app.FindDict("isolation_data");
  EXPECT_TRUE(debug_isolation_data != nullptr);
  EXPECT_EQ(*debug_isolation_data, expected_isolation_data);
}

TEST(WebAppTest, PermissionsPolicyDebugValue) {
  WebApp app{GenerateAppId(/*manifest_id_path=*/std::nullopt,
                           GURL("https://example.com"))};
  app.SetPermissionsPolicy({
      {network::mojom::PermissionsPolicyFeature::kGyroscope,
       /*allowed_origins=*/{},
       /*self_if_matches=*/std::nullopt,
       /*matches_all_origins=*/false,
       /*matches_opaque_src=*/true},
      {network::mojom::PermissionsPolicyFeature::kGeolocation,
       /*allowed_origins=*/{},
       /*self_if_matches=*/std::nullopt,
       /*matches_all_origins=*/true,
       /*matches_opaque_src=*/false},
      {network::mojom::PermissionsPolicyFeature::kGamepad,
       {*network::OriginWithPossibleWildcards::FromOriginAndWildcardsForTest(
            url::Origin::Create(GURL("https://example.com")),
            /*has_subdomain_wildcard=*/false),
        *network::OriginWithPossibleWildcards::FromOriginAndWildcardsForTest(
            url::Origin::Create(GURL("https://example.net")),
            /*has_subdomain_wildcard=*/true)},
       /*self_if_matches=*/std::nullopt,
       /*matches_all_origins=*/false,
       /*matches_opaque_src=*/false},
  });

  EXPECT_TRUE(!app.permissions_policy().empty());

  base::Value expected_permissions_policy = base::JSONReader::Read(R"([
        {
          "allowed_origins": [  ],
          "feature": "gyroscope",
          "matches_all_origins": false,
          "matches_opaque_src": true
        }
        , {
          "allowed_origins": [  ],
          "feature": "geolocation",
          "matches_all_origins": true,
          "matches_opaque_src": false
        }
        , {
          "allowed_origins": [ "https://example.com", "https://*.example.net" ],
          "feature": "gamepad",
          "matches_all_origins": false,
          "matches_opaque_src": false
        }
      ])")
                                                .value();

  base::Value::Dict debug_app = app.AsDebugValue().GetDict().Clone();
  base::Value::List* debug_permissions_policy =
      debug_app.FindList("permissions_policy");
  EXPECT_TRUE(debug_permissions_policy != nullptr);
  EXPECT_EQ(*debug_permissions_policy, expected_permissions_policy);
}

}  // namespace web_app
