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

#include "settingsd/cros_install_attributes.h"

#include <algorithm>
#include <arpa/inet.h>
#include <functional>
#include <memory>
#include <stdint.h>
#include <string>
#include <unordered_map>

#include <base/files/scoped_temp_dir.h>
#include <base/macros.h>
#include <base/values.h>
#include <gtest/gtest.h>

#include "bindings/install_attributes.pb.h"

#include "settingsd/crypto.h"
#include "settingsd/mock_nvram.h"
#include "settingsd/mock_settings_document.h"
#include "settingsd/settings_document_manager.h"
#include "settingsd/settings_keys.h"
#include "settingsd/simple_settings_map.h"
#include "settingsd/test_helpers.h"

namespace settingsd {

namespace {

const char kTestSource[] = "test_source";
const char kTestKey[] = "test.foo";
const char kTestValue[] = "test_value";
const uint32_t kTestNVRamIndex = 42;
const uint8_t
    kTestSalt[CrosInstallAttributesSourceDelegate::kReservedSaltBytesV2] =
        "test salt";

}  // namespace

class CrosInstallAttributesTest : public testing::Test {
 public:
  void SetUp() {
    // Prepare a serialized install attributes blob for testing.
    cryptohome::SerializedInstallAttributes install_attributes;
    cryptohome::SerializedInstallAttributes::Attribute* attribute =
        install_attributes.add_attributes();
    attribute->set_name(kTestKey);
    attribute->set_value(kTestValue);
    ASSERT_TRUE(
        install_attributes.SerializeToString(&install_attributes_blob_));

    // Prepare a mock NVRAM.
    MockNVRam::Space* space = nvram_.GetSpace(kTestNVRamIndex);
    space->locked_for_reading_ = true;
    space->locked_for_writing_ = true;
    InitSpace(install_attributes_blob_, install_attributes_blob_.size(),
              &space->data_);

    // Bring up a SettingsDocumentManager to consumer the blob.
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    manager_.reset(new SettingsDocumentManager(
        CrosInstallAttributesContainer::Parse,
        std::bind(CrosInstallAttributesSourceDelegate::Create, &nvram_,
                  std::placeholders::_1, std::placeholders::_2),
        temp_dir_.path().value(),
        std::unique_ptr<SettingsMap>(new SimpleSettingsMap()),
        MakeTrustedDocument()));
    manager_->Init();
  }

  static void InitSpace(const std::string& data,
                        uint32_t size,
                        std::vector<uint8_t>* space) {
    // Compute the size field.
    space->resize(CrosInstallAttributesSourceDelegate::kReservedNvramBytesV2);
    size = htonl(size);
    for (size_t i = 0; i < sizeof(size); ++i)
      (*space)[i] = (size >> (8 * i)) & 0xff;

    // Put the dummy salt.
    std::copy(kTestSalt, kTestSalt + sizeof(kTestSalt),
              space->begin() +
                  CrosInstallAttributesSourceDelegate::kReservedSizeBytes +
                  CrosInstallAttributesSourceDelegate::kReservedFlagsBytes);

    // Compute the digest.
    std::vector<uint8_t> salted_blob;
    salted_blob.insert(salted_blob.end(), data.begin(), data.end());
    salted_blob.insert(salted_blob.end(), kTestSalt,
                       kTestSalt + sizeof(kTestSalt));
    std::vector<uint8_t> digest;
    ASSERT_TRUE(crypto::ComputeDigest(crypto::kDigestSha256,
                                      BlobRef(&salted_blob), &digest));
    std::copy(digest.begin(), digest.end(),
              space->begin() +
                  CrosInstallAttributesSourceDelegate::kReservedSizeBytes +
                  CrosInstallAttributesSourceDelegate::kReservedFlagsBytes +
                  CrosInstallAttributesSourceDelegate::kReservedSaltBytesV2);
  }

  static std::unique_ptr<SettingsDocument> MakeTrustedDocument() {
    // Prepare a trusted settings document that defines an install attributes
    // source.
    std::unique_ptr<MockSettingsDocument> trusted_document(
        new MockSettingsDocument(VersionStamp()));
    trusted_document->SetKey(
        MakeSourceKey(kTestSource).Extend({keys::sources::kStatus}),
        SettingStatusToString(kSettingStatusActive));
    trusted_document->SetKey(
        MakeSourceKey(kTestSource).Extend({keys::sources::kNVRamIndex}),
        std::to_string(kTestNVRamIndex));
    trusted_document->SetKey(
        MakeSourceKey(kTestSource)
            .Extend({keys::sources::kAccess})
            .Append(Key(kTestKey)),
        SettingStatusToString(kSettingStatusActive));
    return std::move(trusted_document);
  }

  base::ScopedTempDir temp_dir_;
  std::string install_attributes_blob_;
  MockNVRam nvram_;
  std::unique_ptr<SettingsDocumentManager> manager_;
};

TEST_F(CrosInstallAttributesTest, Success) {
  EXPECT_EQ(
      SettingsDocumentManager::kInsertionStatusSuccess,
      manager_->InsertBlob(kTestSource, BlobRef(&install_attributes_blob_)));

  // Verify that the value has shown up.
  EXPECT_TRUE(BlobRef(kTestValue).Equals(manager_->GetValue(Key(kTestKey))));
}

TEST_F(CrosInstallAttributesTest, UndefinedNVRamSpace) {
  nvram_.DeleteSpace(kTestNVRamIndex);
  EXPECT_EQ(
      SettingsDocumentManager::kInsertionStatusValidationError,
      manager_->InsertBlob(kTestSource, BlobRef(&install_attributes_blob_)));
  EXPECT_FALSE(manager_->GetValue(Key(kTestKey)).valid());
}

TEST_F(CrosInstallAttributesTest, UnlockedNVRamSpace) {
  nvram_.GetSpace(kTestNVRamIndex)->locked_for_writing_ = false;
  EXPECT_EQ(
      SettingsDocumentManager::kInsertionStatusValidationError,
      manager_->InsertBlob(kTestSource, BlobRef(&install_attributes_blob_)));
  EXPECT_FALSE(manager_->GetValue(Key(kTestKey)).valid());
}

TEST_F(CrosInstallAttributesTest, BadSize) {
  InitSpace(install_attributes_blob_, 1,
            &nvram_.GetSpace(kTestNVRamIndex)->data_);
  EXPECT_EQ(
      SettingsDocumentManager::kInsertionStatusValidationError,
      manager_->InsertBlob(kTestSource, BlobRef(&install_attributes_blob_)));
  EXPECT_FALSE(manager_->GetValue(Key(kTestKey)).valid());
}

TEST_F(CrosInstallAttributesTest, BadDigest) {
  install_attributes_blob_.back() ^= 0xff;
  EXPECT_EQ(
      SettingsDocumentManager::kInsertionStatusValidationError,
      manager_->InsertBlob(kTestSource, BlobRef(&install_attributes_blob_)));
  EXPECT_FALSE(manager_->GetValue(Key(kTestKey)).valid());
}

}  // namespace settingsd
