// Copyright (c) 2012 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.

#include <CoreFoundation/CoreFoundation.h>

#include "base/basictypes.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/strings/sys_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/policy/async_policy_provider.h"
#include "chrome/browser/policy/configuration_policy_provider_test.h"
#include "chrome/browser/policy/policy_loader_mac.h"
#include "chrome/browser/policy/preferences_mock_mac.h"
#include "components/policy/core/common/external_data_fetcher.h"
#include "components/policy/core/common/policy_bundle.h"
#include "components/policy/core/common/policy_map.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::ScopedCFTypeRef;

namespace policy {

namespace {

// Converts a base::Value to the equivalent CFPropertyListRef.
// The returned value is owned by the caller.
CFPropertyListRef CreatePropertyFromValue(const base::Value* value) {
  switch (value->GetType()) {
    case base::Value::TYPE_NULL:
      return kCFNull;

    case base::Value::TYPE_BOOLEAN: {
      bool bool_value;
      if (value->GetAsBoolean(&bool_value))
        return bool_value ? kCFBooleanTrue : kCFBooleanFalse;
      break;
    }

    case base::Value::TYPE_INTEGER: {
      int int_value;
      if (value->GetAsInteger(&int_value)) {
        return CFNumberCreate(
            kCFAllocatorDefault, kCFNumberIntType, &int_value);
      }
      break;
    }

    case base::Value::TYPE_DOUBLE: {
      double double_value;
      if (value->GetAsDouble(&double_value)) {
        return CFNumberCreate(
            kCFAllocatorDefault, kCFNumberDoubleType, &double_value);
      }
      break;
    }

    case base::Value::TYPE_STRING: {
      std::string string_value;
      if (value->GetAsString(&string_value))
        return base::SysUTF8ToCFStringRef(string_value);
      break;
    }

    case base::Value::TYPE_DICTIONARY: {
      const base::DictionaryValue* dict_value;
      if (value->GetAsDictionary(&dict_value)) {
        // |dict| is owned by the caller.
        CFMutableDictionaryRef dict =
            CFDictionaryCreateMutable(kCFAllocatorDefault,
                                      dict_value->size(),
                                      &kCFTypeDictionaryKeyCallBacks,
                                      &kCFTypeDictionaryValueCallBacks);
        for (base::DictionaryValue::Iterator iterator(*dict_value);
             !iterator.IsAtEnd(); iterator.Advance()) {
          // CFDictionaryAddValue() retains both |key| and |value|, so make sure
          // the references are balanced.
          ScopedCFTypeRef<CFStringRef> key(
              base::SysUTF8ToCFStringRef(iterator.key()));
          ScopedCFTypeRef<CFPropertyListRef> cf_value(
              CreatePropertyFromValue(&iterator.value()));
          if (cf_value)
            CFDictionaryAddValue(dict, key, cf_value);
        }
        return dict;
      }
      break;
    }

    case base::Value::TYPE_LIST: {
      const base::ListValue* list;
      if (value->GetAsList(&list)) {
        CFMutableArrayRef array =
            CFArrayCreateMutable(NULL, list->GetSize(), &kCFTypeArrayCallBacks);
        for (base::ListValue::const_iterator it(list->begin());
             it != list->end(); ++it) {
          // CFArrayAppendValue() retains |value|, so make sure the reference
          // created by CreatePropertyFromValue() is released.
          ScopedCFTypeRef<CFPropertyListRef> cf_value(
              CreatePropertyFromValue(*it));
          if (cf_value)
            CFArrayAppendValue(array, cf_value);
        }
        return array;
      }
      break;
    }

    case base::Value::TYPE_BINARY:
      // This type isn't converted (though it can be represented as CFData)
      // because there's no equivalent JSON type, and policy values can only
      // take valid JSON values.
      break;
  }

  return NULL;
}

class TestHarness : public PolicyProviderTestHarness {
 public:
  TestHarness();
  virtual ~TestHarness();

  virtual void SetUp() OVERRIDE;

  virtual ConfigurationPolicyProvider* CreateProvider(
      SchemaRegistry* registry,
      scoped_refptr<base::SequencedTaskRunner> task_runner) OVERRIDE;

  virtual void InstallEmptyPolicy() OVERRIDE;
  virtual void InstallStringPolicy(const std::string& policy_name,
                                   const std::string& policy_value) OVERRIDE;
  virtual void InstallIntegerPolicy(const std::string& policy_name,
                                    int policy_value) OVERRIDE;
  virtual void InstallBooleanPolicy(const std::string& policy_name,
                                    bool policy_value) OVERRIDE;
  virtual void InstallStringListPolicy(
      const std::string& policy_name,
      const base::ListValue* policy_value) OVERRIDE;
  virtual void InstallDictionaryPolicy(
      const std::string& policy_name,
      const base::DictionaryValue* policy_value) OVERRIDE;

  static PolicyProviderTestHarness* Create();

 private:
  MockPreferences* prefs_;

  DISALLOW_COPY_AND_ASSIGN(TestHarness);
};

TestHarness::TestHarness()
    : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER) {}

TestHarness::~TestHarness() {}

void TestHarness::SetUp() {}

ConfigurationPolicyProvider* TestHarness::CreateProvider(
    SchemaRegistry* registry,
    scoped_refptr<base::SequencedTaskRunner> task_runner) {
  prefs_ = new MockPreferences();
  scoped_ptr<AsyncPolicyLoader> loader(
      new PolicyLoaderMac(task_runner, base::FilePath(), prefs_));
  return new AsyncPolicyProvider(registry, loader.Pass());
}

void TestHarness::InstallEmptyPolicy() {}

void TestHarness::InstallStringPolicy(const std::string& policy_name,
                                      const std::string& policy_value) {
  ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name));
  ScopedCFTypeRef<CFStringRef> value(base::SysUTF8ToCFStringRef(policy_value));
  prefs_->AddTestItem(name, value, true);
}

void TestHarness::InstallIntegerPolicy(const std::string& policy_name,
                                       int policy_value) {
  ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name));
  ScopedCFTypeRef<CFNumberRef> value(
      CFNumberCreate(NULL, kCFNumberIntType, &policy_value));
  prefs_->AddTestItem(name, value, true);
}

void TestHarness::InstallBooleanPolicy(const std::string& policy_name,
                                       bool policy_value) {
  ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name));
  prefs_->AddTestItem(name,
                      policy_value ? kCFBooleanTrue : kCFBooleanFalse,
                      true);
}

void TestHarness::InstallStringListPolicy(const std::string& policy_name,
                                          const base::ListValue* policy_value) {
  ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name));
  ScopedCFTypeRef<CFPropertyListRef> array(
      CreatePropertyFromValue(policy_value));
  ASSERT_TRUE(array);
  prefs_->AddTestItem(name, array, true);
}

void TestHarness::InstallDictionaryPolicy(
    const std::string& policy_name,
    const base::DictionaryValue* policy_value) {
  ScopedCFTypeRef<CFStringRef> name(base::SysUTF8ToCFStringRef(policy_name));
  ScopedCFTypeRef<CFPropertyListRef> dict(
      CreatePropertyFromValue(policy_value));
  ASSERT_TRUE(dict);
  prefs_->AddTestItem(name, dict, true);
}

// static
PolicyProviderTestHarness* TestHarness::Create() {
  return new TestHarness();
}

}  // namespace

// Instantiate abstract test case for basic policy reading tests.
INSTANTIATE_TEST_CASE_P(
    PolicyProviderMacTest,
    ConfigurationPolicyProviderTest,
    testing::Values(TestHarness::Create));

// TODO(joaodasilva): instantiate Configuration3rdPartyPolicyProviderTest too
// once the mac loader supports 3rd party policy. http://crbug.com/108995

// Special test cases for some mac preferences details.
class PolicyLoaderMacTest : public PolicyTestBase {
 protected:
  PolicyLoaderMacTest()
      : prefs_(new MockPreferences()) {}
  virtual ~PolicyLoaderMacTest() {}

  virtual void SetUp() OVERRIDE {
    PolicyTestBase::SetUp();
    scoped_ptr<AsyncPolicyLoader> loader(new PolicyLoaderMac(
        loop_.message_loop_proxy(), base::FilePath(), prefs_));
    provider_.reset(new AsyncPolicyProvider(&schema_registry_, loader.Pass()));
    provider_->Init(&schema_registry_);
  }

  virtual void TearDown() OVERRIDE {
    provider_->Shutdown();
    PolicyTestBase::TearDown();
  }

  MockPreferences* prefs_;
  scoped_ptr<AsyncPolicyProvider> provider_;
};

TEST_F(PolicyLoaderMacTest, Invalid) {
  ScopedCFTypeRef<CFStringRef> name(
      base::SysUTF8ToCFStringRef(test_keys::kKeyString));
  const char buffer[] = "binary \xde\xad\xbe\xef data";
  ScopedCFTypeRef<CFDataRef> invalid_data(
      CFDataCreate(kCFAllocatorDefault,
                   reinterpret_cast<const UInt8 *>(buffer),
                   arraysize(buffer)));
  ASSERT_TRUE(invalid_data);
  prefs_->AddTestItem(name, invalid_data.get(), true);
  prefs_->AddTestItem(name, invalid_data.get(), false);

  // Make the provider read the updated |prefs_|.
  provider_->RefreshPolicies();
  loop_.RunUntilIdle();
  const PolicyBundle kEmptyBundle;
  EXPECT_TRUE(provider_->policies().Equals(kEmptyBundle));
}

TEST_F(PolicyLoaderMacTest, TestNonForcedValue) {
  ScopedCFTypeRef<CFStringRef> name(
      base::SysUTF8ToCFStringRef(test_keys::kKeyString));
  ScopedCFTypeRef<CFPropertyListRef> test_value(
      base::SysUTF8ToCFStringRef("string value"));
  ASSERT_TRUE(test_value.get());
  prefs_->AddTestItem(name, test_value.get(), false);

  // Make the provider read the updated |prefs_|.
  provider_->RefreshPolicies();
  loop_.RunUntilIdle();
  PolicyBundle expected_bundle;
  expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
      .Set(test_keys::kKeyString,
           POLICY_LEVEL_RECOMMENDED,
           POLICY_SCOPE_USER,
           base::Value::CreateStringValue("string value"),
           NULL);
  EXPECT_TRUE(provider_->policies().Equals(expected_bundle));
}

TEST_F(PolicyLoaderMacTest, TestConversions) {
  base::DictionaryValue root;

  // base::Value::TYPE_NULL
  root.Set("null", base::Value::CreateNullValue());

  // base::Value::TYPE_BOOLEAN
  root.SetBoolean("false", false);
  root.SetBoolean("true", true);

  // base::Value::TYPE_INTEGER
  root.SetInteger("int", 123);
  root.SetInteger("zero", 0);

  // base::Value::TYPE_DOUBLE
  root.SetDouble("double", 123.456);
  root.SetDouble("zerod", 0.0);

  // base::Value::TYPE_STRING
  root.SetString("string", "the fox jumps over something");
  root.SetString("empty", "");

  // base::Value::TYPE_LIST
  base::ListValue list;
  root.Set("emptyl", list.DeepCopy());
  for (base::DictionaryValue::Iterator it(root); !it.IsAtEnd(); it.Advance())
    list.Append(it.value().DeepCopy());
  EXPECT_EQ(root.size(), list.GetSize());
  list.Append(root.DeepCopy());
  root.Set("list", list.DeepCopy());

  // base::Value::TYPE_DICTIONARY
  base::DictionaryValue dict;
  root.Set("emptyd", dict.DeepCopy());
  // Very meta.
  root.Set("dict", root.DeepCopy());

  ScopedCFTypeRef<CFPropertyListRef> property(CreatePropertyFromValue(&root));
  ASSERT_TRUE(property);
  scoped_ptr<base::Value> value(
      PolicyLoaderMac::CreateValueFromProperty(property));
  ASSERT_TRUE(value.get());

  EXPECT_TRUE(root.Equals(value.get()));
}

}  // namespace policy
