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

#ifndef CHROME_BROWSER_EXTENSIONS_CWS_INFO_SERVICE_H_
#define CHROME_BROWSER_EXTENSIONS_CWS_INFO_SERVICE_H_

#include <optional>

#include "base/feature_list.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/timer/timer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/extension_id.h"

static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));

class PrefService;
class Profile;

namespace network {
class SharedURLLoaderFactory;
class SimpleURLLoader;
}  // namespace network

namespace extensions {

class Extension;
class ExtensionPrefs;
class ExtensionRegistry;
class BatchGetStoreMetadatasResponse;

BASE_DECLARE_FEATURE(kCWSInfoFastCheck);

// This is an interface class to allow for easy mocking.
class CWSInfoServiceInterface {
 public:
  virtual ~CWSInfoServiceInterface() = default;

  // Synchronously checks if the extension is currently live in CWS.
  // If the information is not available immediately (i.e., not stored in local
  // cache), does not return a value.
  virtual std::optional<bool> IsLiveInCWS(const Extension& extension) const = 0;

  enum class CWSViolationType {
    kNone = 0,
    kMalware = 1,
    kPolicy = 2,
    kMinorPolicy = 3,
    // New enum values must go above here
    kUnknown
  };
  struct CWSInfo {
    // This extension is present in CWS.
    bool is_present = false;
    // This extension is currently published and downloadable from CWS.
    bool is_live = false;
    // The last time the extension was updated in CWS. Only valid if `is_live`
    // is true.
    base::Time last_update_time;
    // The following fields are only valid if `is_present` is true.
    // If the extension has been taken down, i.e., no longer live, this
    // represents the violation type that caused the take-down.
    CWSViolationType violation_type = CWSViolationType::kNone;
    // The extension was unpublished from CWS by the developer a while ago.
    bool unpublished_long_ago = false;
    // The extension does not display proper privacy practice information in
    // CWS.
    bool no_privacy_practice = false;
  };
  virtual std::optional<CWSInfo> GetCWSInfo(
      const Extension& extension) const = 0;

  // Initiates a fetch from CWS if:
  // - at least one installed extension is missing CWS metadata information
  // - Enough time (default: 24 hours) has elapsed since the last time the
  //   metadata was fetched.
  virtual void CheckAndMaybeFetchInfo() = 0;

  class Observer : public base::CheckedObserver {
   public:
    // This callback is invoked when there is a change in store metadata
    // saved by the service.
    virtual void OnCWSInfoChanged() {}
  };
  // Use these methods to (de)register for changes in the CWS metadata retrieved
  // by the service.
  virtual void AddObserver(Observer* observer) = 0;
  virtual void RemoveObserver(Observer* observer) = 0;
};

// This service retrieves information about installed extensions from CWS
// periodically (default: every 24 hours). It is used exclusively on the
// browser UI thread. The service also supports out-of-cycle fetch requests for
// use cases where waiting for up to 24 hours for fresh state is not desirable
// (for example, when the ExtensionsUnpublishedAvailability policy setting
// changes). Only extensions that update from CWS are queried.
class CWSInfoService : public CWSInfoServiceInterface, public KeyedService {
 public:
  // Convenience method to get the service for a profile.
  static CWSInfoService* Get(Profile* profile);

  explicit CWSInfoService(Profile* profile);

  CWSInfoService(const CWSInfoService&) = delete;
  CWSInfoService& operator=(const CWSInfoService&) = delete;
  ~CWSInfoService() override;

  // CWSInfoServiceInterface:
  std::optional<bool> IsLiveInCWS(const Extension& extension) const override;
  std::optional<CWSInfo> GetCWSInfo(const Extension& extension) const override;
  void CheckAndMaybeFetchInfo() override;
  void AddObserver(Observer* observer) override;
  void RemoveObserver(Observer* observer) override;

  // KeyedService:
  void Shutdown() override;

  // Helpers
  static CWSInfoService::CWSViolationType GetViolationTypeFromString(
      const std::string& violation_type_str);

  // Testing helpers
  std::string GetRequestURLForTesting() const;
  int GetStartupDelayForTesting() const;
  int GetCheckIntervalForTesting() const;
  int GetFetchIntervalForTesting() const;
  base::Time GetCWSInfoTimestampForTesting() const;
  base::Time GetCWSInfoFetchErrorTimestampForTesting() const;
  void SetMaxExtensionIdsPerRequestForTesting(int max);
  static void SetSkipApiCheckForTesting(bool skip_api_key_check);

 protected:
  // Only used for testing to create a fake derived class.
  CWSInfoService();

  // This method schedules an info check after specified `seconds`.
  void ScheduleCheck(int seconds);

  // This method prepares request protos to fetch CWS metadata. A CWS fetch
  // operation can consist of multiple request protos when the number of
  // installed extensions exceeds the max ids supported per request (100). The
  // request protos, extension ids and other data associated with the fetch are
  // returned in a `FetchContext`. The method also outputs a
  // `new_info_requested` that indicates if at least one of the installed
  // extensions is missing CWS metadata information.
  struct FetchContext;
  std::unique_ptr<FetchContext> CreateRequests(
      bool& /*output=*/new_info_requested);

  // Sends a single network request associated with a CWS info fetch.
  void SendRequest();

  // Handles the server response associated with a single network request.
  void OnResponseReceived(std::unique_ptr<std::string> response);

  // Saves data to prefs if the response data is different from the saved data.
  // Returns true if the response data is saved, false otherwise.
  bool MaybeSaveResponseToPrefs(
      const BatchGetStoreMetadatasResponse& response_proto);

  const raw_ptr<Profile> profile_ = nullptr;
  const raw_ptr<PrefService> pref_service_ = nullptr;
  const raw_ptr<ExtensionPrefs> extension_prefs_ = nullptr;
  const raw_ptr<ExtensionRegistry> extension_registry_ = nullptr;

  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
  std::unique_ptr<network::SimpleURLLoader> url_loader_;

  // Stores context about a fetch operation in progress. The service only
  // supports one fetch operation at a time.
  std::unique_ptr<FetchContext> active_fetch_;
  // Each request associated with a fetch can have a maximum of 100 extension
  // ids. This parameter can be changed for testing.
  int max_ids_per_request_;

  // Stats for requests, responses and errors.
  uint32_t info_requests_ = 0;
  uint32_t info_responses_ = 0;
  uint32_t info_errors_ = 0;
  // Counts the number of times the downloaded metadata was different from that
  // currently saved.
  uint32_t info_changes_ = 0;
  // A timer used to periodically check if CWS information needs to be fetched.
  base::OneShotTimer info_check_timer_;
  // Time from startup to first check of CWS information.
  int startup_delay_secs_ = 0;
  // Time interval between fetches from CWS info server. The interval value
  // varies +/-25% from default of 24 hours for every fetch.
  int current_fetch_interval_secs_ = 0;

  // List of observers that are notified whenever new CWS information is saved.
  base::ObserverList<Observer> observers_;

  friend class CWSInfoServiceTest;

  base::WeakPtrFactory<CWSInfoService> weak_factory_{this};
};

}  // namespace extensions

#endif  // CHROME_BROWSER_EXTENSIONS_CWS_INFO_SERVICE_H_
