// Copyright 2018 The Chromium OS 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 SHILL_PROFILE_H_
#define SHILL_PROFILE_H_

#include <memory>
#include <string>
#include <vector>

#include <base/files/file_path.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST

#include "shill/property_store.h"
#include "shill/refptr_types.h"

namespace shill {

class Error;
class Manager;
class Metrics;
class ProfileAdaptorInterface;
class StoreInterface;

class Profile : public base::RefCounted<Profile> {
 public:
  enum InitStorageOption { kOpenExisting, kCreateNew, kCreateOrOpenExisting };
  struct Identifier {
    Identifier() = default;
    explicit Identifier(const std::string& i) : identifier(i) {}
    Identifier(const std::string& u, const std::string& i)
        : user(u), identifier(i) {}
    std::string user;  // Empty for global.
    std::string identifier;
    std::string user_hash;
  };

  // Set of Profile properties to be get/set via PropertyStore calls, provided
  // with helpers to read and save them to persistent storage.
  struct Properties {
    Properties(std::string mode, std::string service)
        : always_on_vpn_mode(mode), always_on_vpn_service(service) {}
    // Describes how the always-on VPN will be handled.
    std::string always_on_vpn_mode;
    // Identifier of the service automatically started when always-on VPN is
    // enabled.
    std::string always_on_vpn_service;

    // Loads properties values from the storage.
    void Load(StoreInterface* storage);
    // Stores properties values to the storage.
    void Save(StoreInterface* storage);
  };

  // Path to the cached list of inserted user profiles to be loaded at
  // startup.
  static const char kUserProfileListPathname[];

  Profile(Manager* manager,
          const Identifier& name,
          const base::FilePath& storage_directory,
          bool connect_to_rpc);
  Profile(const Profile&) = delete;
  Profile& operator=(const Profile&) = delete;

  virtual ~Profile();

  // Set up persistent storage for this Profile.
  bool InitStorage(InitStorageOption storage_option, Error* error);

  // Set up stub storage for this Profile. The data will NOT be
  // persisted. In most cases, you should prefer InitStorage.
  void InitStubStorage();

  // Remove the persistent storage for this Profile.  It is an error to
  // do so while the underlying storage is open via InitStorage() or
  // SetStorageForTest().
  bool RemoveStorage(Error* error);

  virtual std::string GetFriendlyName() const;

  virtual const RpcIdentifier& GetRpcIdentifier() const;

  PropertyStore* mutable_store() { return &store_; }
  const PropertyStore& store() const { return store_; }

  // Set the storage inteface.  This is used for testing purposes.
  void SetStorageForTest(std::unique_ptr<StoreInterface> storage);

  // Begin managing the persistence of |service|.
  // Returns true if |service| is new to this profile and was added,
  // false if the |service| already existed.
  virtual bool AdoptService(const ServiceRefPtr& service);

  // Cease managing the persistence of the Service |service|.
  // Returns true if |service| was found and abandoned, or not found.
  // Returns false if can't be abandoned.
  virtual bool AbandonService(const ServiceRefPtr& service);

  // Clobbers persisted notion of |service| with data from |service|.
  // Returns true if |service| was found and updated, false if not found.
  virtual bool UpdateService(const ServiceRefPtr& service);

  // Ask |service| if it can configure itself from the profile.  If it can,
  // ask |service| to perform the configuration and return true.  If not,
  // return false.
  virtual bool LoadService(const ServiceRefPtr& service);

  // Perform LoadService() on |service|.  If this succeeds, change
  // the service to point at this profile and return true.  If not, return
  // false.
  virtual bool ConfigureService(const ServiceRefPtr& service);

  // Allow the device to configure itself from this profile.  Returns
  // true if the device succeeded in finding its configuration.  If not,
  // return false.
  virtual bool ConfigureDevice(const DeviceRefPtr& device);

  // Remove a named entry from the profile.  This includes detaching
  // any service that uses this profile entry.
  virtual void DeleteEntry(const std::string& entry_name, Error* error);

  // Return a service configured from the given profile entry.
  // Callers must not register the returned service with the Manager or connect
  // it since it might not be in the provider's service list.
  virtual ServiceRefPtr GetServiceFromEntry(const std::string& entry_name,
                                            Error* error);

  // Return whether |service| can configure itself from the profile.
  bool ContainsService(const ServiceConstRefPtr& service);

  RpcIdentifiers EnumerateAvailableServices(Error* error);
  std::vector<std::string> EnumerateEntries(Error* error);

  // Clobbers persisted notion of |device| with data from |device|. Returns true
  // if |device| was found and updated, false otherwise. The base implementation
  // always returns false -- currently devices are persisted only in
  // DefaultProfile.
  virtual bool UpdateDevice(const DeviceRefPtr& device);

  // Write all in-memory state to disk via |storage_|.
  virtual bool Save();

  // Parses a profile identifier. There're two acceptable forms of the |raw|
  // identifier: "identifier" and "~user/identifier". Both "user" and
  // "identifier" must be suitable for use in a D-Bus object path. Returns true
  // on success.
  static bool ParseIdentifier(const std::string& raw, Identifier* parsed);

  // Returns the composite string identifier for a profile, as would have
  // been used in an argument to Manager::PushProfile() in creating this
  // profile.  It returns a string in the form "identifier", or
  // "~user/identifier" depending on whether this profile has a user
  // component.
  static std::string IdentifierToString(const Identifier& name);

  // Load a list of user profile identifiers from a cache file |path|.
  // The profiles themselves are not loaded.
  static std::vector<Identifier> LoadUserProfileList(
      const base::FilePath& path);

  // Save a list of user profile identifiers |profiles| to a cache file |path|.
  // Returns true if successful, false otherwise.
  static bool SaveUserProfileList(const base::FilePath& path,
                                  const std::vector<ProfileRefPtr>& profiles);

  // Returns whether |name| matches this Profile's |name_|.
  virtual bool MatchesIdentifier(const Identifier& name) const;

  // Returns the username component of the profile identifier.
  const std::string& GetUser() const { return name_.user; }

  // Returns the user_hash component of the profile identifier.
  const std::string& GetUserHash() const { return name_.user_hash; }

  // Returns the always-on VPN configuration.
  virtual bool GetAlwaysOnVpnSettings(std::string* mode, RpcIdentifier* id);

  // Clears the profile always-on VPN configuration.
  virtual void ClearAlwaysOnVpn();

  virtual StoreInterface* GetStorage() { return storage_.get(); }

  // Returns a read-only copy of the backing storage of the profile.
  virtual const StoreInterface* GetConstStorage() const {
    return storage_.get();
  }

  virtual bool IsDefault() const { return false; }

 protected:
  // Storage group for user wide properties.
  static constexpr char kStorageId[] = "global";
  // Returns the persistent store file path for a Profile with the
  // given |storage_dir| and |profile_name|. Provided as a static
  // method, so that tests can use this logic without having to
  // instantiate a Profile.
  static base::FilePath GetFinalStoragePath(const base::FilePath& storage_dir,
                                            const Identifier& profile_name);

  Metrics* metrics() const;
  Manager* manager() const { return manager_; }
  StoreInterface* storage() { return storage_.get(); }

  const base::FilePath& persistent_profile_path() const {
    return persistent_profile_path_;
  }
  void set_persistent_profile_path(const base::FilePath& path) {
    persistent_profile_path_ = path;
  }

 private:
  friend class ManagerTest;
  friend class ProfileAdaptorInterface;
  FRIEND_TEST(ManagerTest, CreateDuplicateProfileWithMissingKeyfile);
  FRIEND_TEST(ManagerTest, RemoveProfile);
  FRIEND_TEST(ProfileTest, DeleteEntry);
  FRIEND_TEST(ProfileTest, GetStoragePath);
  FRIEND_TEST(ProfileTest, IsValidIdentifierToken);
  FRIEND_TEST(ProfileTest, GetServiceFromEntry);

  static constexpr char kDefaultAlwaysOnVpnService[] = "";

  static bool IsValidIdentifierToken(const std::string& token);

  void HelpRegisterConstDerivedRpcIdentifiers(
      const std::string& name, RpcIdentifiers (Profile::*get)(Error* error));
  void HelpRegisterConstDerivedStrings(const std::string& name,
                                       Strings (Profile::*get)(Error* error));
  void HelpRegisterDerivedRpcIdentifier(
      const std::string& name,
      RpcIdentifier (Profile::*get)(Error* error),
      bool (Profile::*set)(const RpcIdentifier&, Error*));
  void HelpRegisterDerivedString(const std::string& name,
                                 std::string (Profile::*get)(Error* error),
                                 bool (Profile::*set)(const std::string&,
                                                      Error*));
  void OnPropertyChanged(const std::string& name);
  std::string DBusGetAlwaysOnVpnMode(Error* error);
  bool DBusSetAlwaysOnVpnMode(const std::string& mode, Error* error);
  RpcIdentifier DBusGetAlwaysOnVpnService(Error* error);
  bool DBusSetAlwaysOnVpnService(const RpcIdentifier& id, Error* error);

  // Data members shared with subclasses via getter/setters above in the
  // protected: section
  Manager* manager_;
  base::FilePath persistent_profile_path_;

  // Properties to be get/set via PropertyStore calls.
  Properties properties_;

  // Shared with |adaptor_| via public getter.
  PropertyStore store_;

  // Properties to be gotten via PropertyStore calls.
  Identifier name_;

  // Allows this profile to be backed with on-disk storage.
  std::unique_ptr<StoreInterface> storage_;

  std::unique_ptr<ProfileAdaptorInterface> adaptor_;
};

}  // namespace shill

#endif  // SHILL_PROFILE_H_
