// Copyright 2014 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 LOGIN_MANAGER_SERVER_BACKED_STATE_KEY_GENERATOR_H_
#define LOGIN_MANAGER_SERVER_BACKED_STATE_KEY_GENERATOR_H_

#include <stdint.h>

#include <map>
#include <string>
#include <vector>

#include <base/callback.h>
#include <base/files/file_path.h>
#include <base/macros.h>

namespace login_manager {

class ChildOutputCollector;
class LoginMetrics;
class SystemUtils;

// Generates time-based opaque device identifiers used as keys in server-side
// device state storage. This allows persisting device-specific data on the
// server that survives device recovery and can be restored afterwards.
//
// Identifiers are generated by running a number of stable hardware identifiers
// along with a quantized time stamp through a cryptographic hash function. The
// resulting identifiers shouldn't be predictable by servers, so it's important
// to include hardware identifiers that are only known to the device.
//
// Quantized time is included in order to avoid sharing stable device
// identifiers with the server. This improves privacy, since the server will
// only be able to track the device within the validity time of the identifiers
// it has collected. Once the device stops sharing identifiers, it will
// eventually regain anonymity.
class ServerBackedStateKeyGenerator {
 public:
  // Callback type for state key generation requests.
  typedef base::Callback<void(const std::vector<std::vector<uint8_t>>&)>
      StateKeyCallback;

  // The power of two determining the size of the time quanta for device state
  // keys, i.e. the quanta will be of size 2^kDeviceStateKeyTimeQuantumPower
  // seconds. 2^23 seconds corresponds to 97.09 days.
  static const int kDeviceStateKeyTimeQuantumPower = 23;

  // The number of future time quanta to generate device state identifiers for.
  // This determines the interval after which a device will no longer receive
  // server-backed state information and thus corresponds to the delay until a
  // device becomes anonymous to the server again.
  //
  // The goal here is to guarantee state key validity for 1 year into the
  // future. 4 quanta are needed to cover a year, but the current quantum is
  // clipped short in the general case. Hence, one buffer quantum is needed to
  // make up for the clipping, yielding a total of 5 quanta.
  static const int kDeviceStateKeyFutureQuanta = 5;

  ServerBackedStateKeyGenerator(SystemUtils* system_utils,
                                LoginMetrics* metrics);
  virtual ~ServerBackedStateKeyGenerator();

  // Parses a machine information string containing newline-separated key=value
  // pairs. Removes quoting from names and values. Returns true if parsing is
  // successful.
  static bool ParseMachineInfo(const std::string& data,
                               std::map<std::string, std::string>* params);

  // Sets a machine information parameters. Returns false if a parameter is
  // missing.
  bool InitMachineInfo(const std::map<std::string, std::string>& params);

  // Requests the currently-valid state keys to be computed based on system
  // time. It is the responsibility of the caller to ensure that the system time
  // is accurate before starting the request! The state keys (sorted by time
  // quantum in ascending order) are returned via |callback|, potentially after
  // waiting for machine info to become available. If the state keys can't be
  // computed due to missing machine identifiers, |callback| will be invoked
  // with an empty vector.
  virtual void RequestStateKeys(const StateKeyCallback& callback);

 private:
  // Computes the keys and stores them in |state_keys|. In case of error,
  // |state_keys| will be cleared.
  void ComputeKeys(std::vector<std::vector<uint8_t>>* state_keys);

  SystemUtils* system_utils_;
  LoginMetrics* metrics_;

  // Pending state key generation callbacks.
  std::vector<StateKeyCallback> pending_callbacks_;

  // The data required to generate state keys.
  bool machine_info_available_ = false;
  std::string stable_device_secret_;

  // TODO(mnissler): Remove these and the corresponding code once the old way
  // of generating state keys is no longer used in the wild, i.e. all devices
  // can be assumed to have a stable device secret.
  std::string machine_serial_number_;
  std::string disk_serial_number_;
  std::string group_code_key_;

  DISALLOW_COPY_AND_ASSIGN(ServerBackedStateKeyGenerator);
};

}  // namespace login_manager

#endif  // LOGIN_MANAGER_SERVER_BACKED_STATE_KEY_GENERATOR_H_
