// Copyright 2017 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 AUTHPOLICY_POLICY_POLICY_ENCODER_TEST_BASE_H_
#define AUTHPOLICY_POLICY_POLICY_ENCODER_TEST_BASE_H_

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

#include <base/strings/string_number_conversions.h>
#include <base/values.h>
#include <components/policy/core/common/registry_dict.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

namespace policy {

// Base class for UserPolicyEncoderTest and DevicePolicyEncoderTest. T_POLICY
// is the type of the policy and should either be
// enterprise_management::CloudPolicySettings or
// enterprise_management::ChromeDeviceSettingsProto.
template <typename T_POLICY>
class PolicyEncoderTestBase : public ::testing::Test {
 public:
  PolicyEncoderTestBase() {}
  ~PolicyEncoderTestBase() override {}

 protected:
  // Set registry key base path at which values are set (for extension policy).
  void SetPath(std::initializer_list<const char*> path) { path_ = path; }

  // Clears |policy|, encodes |value| as value for the boolean policy |key| and
  // marks |key| as handled.
  void EncodeBoolean(T_POLICY* policy, const char* key, bool value) {
    EncodeValue(policy, key, std::make_unique<base::Value>(value));
  }

  // Clears |policy|, encodes |value| as value for the integer policy |key| and
  // marks |key| as handled.
  void EncodeInteger(T_POLICY* policy, const char* key, int value) {
    EncodeValue(policy, key, std::make_unique<base::Value>(value));
  }

  // Clears |policy|, encodes |value| as value for the string policy |key| and
  // marks |key| as handled.
  void EncodeString(T_POLICY* policy,
                    const char* key,
                    const std::string& value) {
    EncodeValue(policy, key, std::make_unique<base::Value>(value));
  }

  // Clears |policy|, encodes |value| as value for the string list policy |key|
  // and marks |key| as handled.
  void EncodeStringList(T_POLICY* policy,
                        const char* key,
                        const std::vector<std::string>& value) {
    auto value_dict = std::make_unique<RegistryDict>();
    for (int n = 0; n < static_cast<int>(value.size()); ++n) {
      value_dict->SetValue(base::NumberToString(n + 1),
                           std::make_unique<base::Value>(value[n]));
    }
    std::unique_ptr<RegistryDict> root_dict;
    RegistryDict* dict = MakeRegistryDictTree(&root_dict);
    dict->SetKey(key, std::move(value_dict));
    EncodeDict(policy, root_dict.get());
    MarkHandled(key);
  }

  // Called by all of the Encode* methods. Override to keep track of encoded
  // policies.
  virtual void MarkHandled(const char* /* key */) {}

  // Uses a policy encoder to write |dict| to |policy|.
  virtual void EncodeDict(T_POLICY* policy, const RegistryDict* dict) = 0;

 private:
  // Creates a RegistryDict sequence along |path_| with |root_dict| at the root
  // and the return value at the leaf.
  RegistryDict* MakeRegistryDictTree(std::unique_ptr<RegistryDict>* root_dict) {
    *root_dict = std::make_unique<RegistryDict>();
    RegistryDict* curr_dict = root_dict->get();
    for (const char* subkey : path_) {
      curr_dict->SetKey(subkey, std::make_unique<RegistryDict>());
      curr_dict = curr_dict->GetKey(subkey);
    }
    return curr_dict;
  }

  // Clears |policy|, encodes |value| as value for the given |key| and marks
  // |key| as handled.
  void EncodeValue(T_POLICY* policy,
                   const char* key,
                   std::unique_ptr<base::Value> value) {
    std::unique_ptr<RegistryDict> root_dict;
    RegistryDict* dict = MakeRegistryDictTree(&root_dict);
    dict->SetValue(key, std::move(value));
    EncodeDict(policy, root_dict.get());
    MarkHandled(key);
  }

  // Registry key path at which values are set, e.g.
  //   {"gihmafigllmhbppdfjnfecimiohcljba", "Policy"}
  // for extension policy.
  std::vector<const char*> path_;

  DISALLOW_COPY_AND_ASSIGN(PolicyEncoderTestBase);
};

}  // namespace policy

#endif  // AUTHPOLICY_POLICY_POLICY_ENCODER_TEST_BASE_H_
