// Copyright 2017 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.

#ifndef COMPONENTS_UPDATE_CLIENT_COMPONENT_H_
#define COMPONENTS_UPDATE_CLIENT_COMPONENT_H_

#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "base/version.h"
#include "components/update_client/crx_downloader.h"
#include "components/update_client/protocol_parser.h"
#include "components/update_client/update_client.h"
#include "url/gurl.h"

#if defined(STARBOARD)
#include "cobalt/extension/installation_manager.h"
#endif

namespace base {
class Value;
}  // namespace base

namespace update_client {

class ActionRunner;
class Configurator;
struct CrxUpdateItem;
struct UpdateContext;

// Describes a CRX component managed by the UpdateEngine. Each |Component| is
// associated with an UpdateContext.
class Component {
 public:
  using Events = UpdateClient::Observer::Events;

  using CallbackHandleComplete = base::OnceCallback<void()>;

  Component(const UpdateContext& update_context, const std::string& id);
  ~Component();

  // Handles the current state of the component and makes it transition
  // to the next component state before |callback_handle_complete_| is invoked.
  void Handle(CallbackHandleComplete callback_handle_complete);

#if defined(STARBOARD)
  // Stops update progress for the component and may clean resources used in its
  // current state.
  void Cancel();
#endif

  CrxUpdateItem GetCrxUpdateItem() const;

  // Sets the uninstall state for this component.
  void Uninstall(const base::Version& cur_version, int reason);

  // Called by the UpdateEngine when an update check for this component is done.
  void SetUpdateCheckResult(
      const base::Optional<ProtocolParser::Result>& result,
      ErrorCategory error_category,
      int error);

  // Returns true if the component has reached a final state and no further
  // handling and state transitions are possible.
  bool IsHandled() const { return is_handled_; }

  // Returns true if an update is available for this component, meaning that
  // the update server has return a response containing an update.
  bool IsUpdateAvailable() const { return is_update_available_; }

  base::TimeDelta GetUpdateDuration() const;

  ComponentState state() const { return state_->state(); }

  std::string id() const { return id_; }

  const base::Optional<CrxComponent>& crx_component() const {
    return crx_component_;
  }
  void set_crx_component(const CrxComponent& crx_component) {
    crx_component_ = crx_component;
  }

  const base::Version& previous_version() const { return previous_version_; }
  void set_previous_version(const base::Version& previous_version) {
    previous_version_ = previous_version;
  }

  const base::Version& next_version() const { return next_version_; }

  std::string previous_fp() const { return previous_fp_; }
  void set_previous_fp(const std::string& previous_fp) {
    previous_fp_ = previous_fp;
  }

  std::string next_fp() const { return next_fp_; }
  void set_next_fp(const std::string& next_fp) { next_fp_ = next_fp; }

  bool is_foreground() const;

  const std::vector<GURL>& crx_diffurls() const { return crx_diffurls_; }

  bool diff_update_failed() const { return !!diff_error_code_; }

  ErrorCategory error_category() const { return error_category_; }
  int error_code() const { return error_code_; }
  int extra_code1() const { return extra_code1_; }
  ErrorCategory diff_error_category() const { return diff_error_category_; }
  int diff_error_code() const { return diff_error_code_; }
  int diff_extra_code1() const { return diff_extra_code1_; }

  std::string action_run() const { return action_run_; }

  scoped_refptr<Configurator> config() const;

  std::string session_id() const;

  const std::vector<base::Value>& events() const { return events_; }

  // Returns a clone of the component events.
  std::vector<base::Value> GetEvents() const;

 private:
#if defined(STARBOARD)
  bool is_cancelled_ = false;
#endif
  friend class MockPingManagerImpl;
  friend class UpdateCheckerTest;

  FRIEND_TEST_ALL_PREFIXES(PingManagerTest, SendPing);
  FRIEND_TEST_ALL_PREFIXES(PingManagerTest, RequiresEncryption);
  FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, NoUpdateActionRun);
  FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckCupError);
  FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckError);
  FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckInvalidAp);
  FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest,
                           UpdateCheckRequiresEncryptionError);
  FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckSuccess);
  FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckUpdateDisabled);

  // Describes an abstraction for implementing the behavior of a component and
  // the transition from one state to another.
  class State {
   public:
    using CallbackNextState =
        base::OnceCallback<void(std::unique_ptr<State> next_state)>;

    State(Component* component, ComponentState state);
    virtual ~State();

    // Handles the current state and initiates a transition to a new state.
    // The transition to the new state is non-blocking and it is completed
    // by the outer component, after the current state is fully handled.
    void Handle(CallbackNextState callback);

#if defined(STARBOARD)
    // Stops update progress and may clean resources used in the current state.
    virtual void Cancel();
#endif

    ComponentState state() const { return state_; }

#if defined(STARBOARD)
    std::string state_name() {
      switch (state_) {
        case ComponentState::kNew:
          return "New";
        case ComponentState::kChecking:
          return "Checking";
        case ComponentState::kCanUpdate:
          return "CanUpdate";
        case ComponentState::kDownloadingDiff:
          return "DownloadingDiff";
        case ComponentState::kDownloading:
          return "Downloaded";
        case ComponentState::kUpdatingDiff:
          return "UpdatingDiff";
        case ComponentState::kUpdating:
          return "Updating";
        case ComponentState::kUpdated:
          return "Updated";
        case ComponentState::kUpToDate:
          return  "UpToDate";
        case ComponentState::kUpdateError:
          return "UpdateError";
        case ComponentState::kUninstalled:
          return "Uninstalled";
        case ComponentState::kRun:
          return "Run";
        case ComponentState::kLastStatus:
          return "LastStatus";
        default:
          return "Unknown";
      }
    }
#endif

   protected:
    // Initiates the transition to the new state.
    void TransitionState(std::unique_ptr<State> new_state);

    // Makes the current state a final state where no other state transition
    // can further occur.
    void EndState();

    Component& component() { return component_; }
    const Component& component() const { return component_; }

    base::ThreadChecker thread_checker_;

    const ComponentState state_;

   private:
    virtual void DoHandle() = 0;

    Component& component_;
    CallbackNextState callback_next_state_;
  };

  class StateNew : public State {
   public:
    explicit StateNew(Component* component);
    ~StateNew() override;

   private:
    // State overrides.
    void DoHandle() override;

    DISALLOW_COPY_AND_ASSIGN(StateNew);
  };

  class StateChecking : public State {
   public:
    explicit StateChecking(Component* component);
    ~StateChecking() override;

   private:
    // State overrides.
    void DoHandle() override;

    void UpdateCheckComplete();

    DISALLOW_COPY_AND_ASSIGN(StateChecking);
  };

  class StateUpdateError : public State {
   public:
    explicit StateUpdateError(Component* component);
    ~StateUpdateError() override;

   private:
    // State overrides.
    void DoHandle() override;

    DISALLOW_COPY_AND_ASSIGN(StateUpdateError);
  };

  class StateCanUpdate : public State {
   public:
    explicit StateCanUpdate(Component* component);
    ~StateCanUpdate() override;

   private:
    // State overrides.
    void DoHandle() override;
    bool CanTryDiffUpdate() const;

    DISALLOW_COPY_AND_ASSIGN(StateCanUpdate);
  };

  class StateUpToDate : public State {
   public:
    explicit StateUpToDate(Component* component);
    ~StateUpToDate() override;

   private:
    // State overrides.
    void DoHandle() override;

    DISALLOW_COPY_AND_ASSIGN(StateUpToDate);
  };

  class StateDownloadingDiff : public State {
   public:
    explicit StateDownloadingDiff(Component* component);
    ~StateDownloadingDiff() override;
#if defined(STARBOARD)
    void Cancel() override;
#endif

   private:
    // State overrides.
    void DoHandle() override;

    // Called when progress is being made downloading a CRX. Can be called
    // multiple times due to how the CRX downloader switches between
    // different downloaders and fallback urls.
    void DownloadProgress(const std::string& id);

    void DownloadComplete(const std::string& id,
                          const CrxDownloader::Result& download_result);

    // Downloads updates for one CRX id only.
    std::unique_ptr<CrxDownloader> crx_downloader_;

    DISALLOW_COPY_AND_ASSIGN(StateDownloadingDiff);
  };

  class StateDownloading : public State {
   public:
    explicit StateDownloading(Component* component);
    ~StateDownloading() override;
#if defined(STARBOARD)
    void Cancel() override;
#endif

   private:
    // State overrides.
    void DoHandle() override;

    // Called when progress is being made downloading a CRX. Can be called
    // multiple times due to how the CRX downloader switches between
    // different downloaders and fallback urls.
    void DownloadProgress(const std::string& id);

    void DownloadComplete(const std::string& id,
                          const CrxDownloader::Result& download_result);

    // Downloads updates for one CRX id only.
    std::unique_ptr<CrxDownloader> crx_downloader_;

    DISALLOW_COPY_AND_ASSIGN(StateDownloading);
  };

  class StateUpdatingDiff : public State {
   public:
    explicit StateUpdatingDiff(Component* component);
    ~StateUpdatingDiff() override;

   private:
    // State overrides.
    void DoHandle() override;

    void InstallComplete(ErrorCategory error_category,
                         int error_code,
                         int extra_code1);

    DISALLOW_COPY_AND_ASSIGN(StateUpdatingDiff);
  };

  class StateUpdating : public State {
   public:
    explicit StateUpdating(Component* component);
    ~StateUpdating() override;

   private:
    // State overrides.
    void DoHandle() override;

    void InstallComplete(ErrorCategory error_category,
                         int error_code,
                         int extra_code1);

    DISALLOW_COPY_AND_ASSIGN(StateUpdating);
  };

  class StateUpdated : public State {
   public:
    explicit StateUpdated(Component* component);
    ~StateUpdated() override;

   private:
    // State overrides.
    void DoHandle() override;

    DISALLOW_COPY_AND_ASSIGN(StateUpdated);
  };

  class StateUninstalled : public State {
   public:
    explicit StateUninstalled(Component* component);
    ~StateUninstalled() override;

   private:
    // State overrides.
    void DoHandle() override;

    DISALLOW_COPY_AND_ASSIGN(StateUninstalled);
  };

  class StateRun : public State {
   public:
    explicit StateRun(Component* component);
    ~StateRun() override;

   private:
    // State overrides.
    void DoHandle() override;

    void ActionRunComplete(bool succeeded, int error_code, int extra_code1);

    // Runs the action referred by the |action_run_| member of the Component
    // class.
    std::unique_ptr<ActionRunner> action_runner_;

    DISALLOW_COPY_AND_ASSIGN(StateRun);
  };

  // Returns true is the update payload for this component can be downloaded
  // by a downloader which can do bandwidth throttling on the client side.
  bool CanDoBackgroundDownload() const;

  void AppendEvent(base::Value event);

  // Changes the component state and notifies the caller of the |Handle|
  // function that the handling of this component state is complete.
  void ChangeState(std::unique_ptr<State> next_state);

  // Notifies registered observers about changes in the state of the component.
  void NotifyObservers(Events event) const;

  void SetParseResult(const ProtocolParser::Result& result);

  // These functions return a specific event. Each data member of the event is
  // represented as a key-value pair in a dictionary value.
  base::Value MakeEventUpdateComplete() const;
  base::Value MakeEventDownloadMetrics(
      const CrxDownloader::DownloadMetrics& download_metrics) const;
  base::Value MakeEventUninstalled() const;
  base::Value MakeEventActionRun(bool succeeded,
                                 int error_code,
                                 int extra_code1) const;

  base::ThreadChecker thread_checker_;

  const std::string id_;
  base::Optional<CrxComponent> crx_component_;

  // The status of the updatecheck response.
  std::string status_;

  // Time when an update check for this CRX has happened.
  base::TimeTicks last_check_;

  // Time when the update of this CRX has begun.
  base::TimeTicks update_begin_;

  // A component can be made available for download from several urls.
  std::vector<GURL> crx_urls_;
  std::vector<GURL> crx_diffurls_;

  // The cryptographic hash values for the component payload.
  std::string hash_sha256_;
  std::string hashdiff_sha256_;

  // The from/to version and fingerprint values.
  base::Version previous_version_;
  base::Version next_version_;
  std::string previous_fp_;
  std::string next_fp_;

  // Contains the file name of the payload to run. This member is set by
  // the update response parser, when the update response includes a run action.
  std::string action_run_;

  // True if the update check response for this component includes an update.
  bool is_update_available_ = false;

  // The error reported by the update checker.
  int update_check_error_ = 0;

  base::FilePath crx_path_;

#if defined(STARBOARD)
  int installation_index_ = IM_EXT_INVALID_INDEX;
#endif

  // The error information for full and differential updates.
  // The |error_category| contains a hint about which module in the component
  // updater generated the error. The |error_code| constains the error and
  // the |extra_code1| usually contains a system error, but it can contain
  // any extended information that is relevant to either the category or the
  // error itself.
  ErrorCategory error_category_ = ErrorCategory::kNone;
  int error_code_ = 0;
  int extra_code1_ = 0;
  ErrorCategory diff_error_category_ = ErrorCategory::kNone;
  int diff_error_code_ = 0;
  int diff_extra_code1_ = 0;

  // Contains the events which are therefore serialized in the requests.
  std::vector<base::Value> events_;

  CallbackHandleComplete callback_handle_complete_;
  std::unique_ptr<State> state_;
  const UpdateContext& update_context_;

  base::OnceClosure update_check_complete_;

  ComponentState previous_state_ = ComponentState::kLastStatus;

  // True if this component has reached a final state because all its states
  // have been handled.
  bool is_handled_ = false;

  DISALLOW_COPY_AND_ASSIGN(Component);
};

using IdToComponentPtrMap = std::map<std::string, std::unique_ptr<Component>>;

}  // namespace update_client

#endif  // COMPONENTS_UPDATE_CLIENT_COMPONENT_H_
