// 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 "chromeos/network/onc/onc_validator.h"

#include <string>
#include <utility>

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "chromeos/network/onc/onc_constants.h"
#include "chromeos/network/onc/onc_signature.h"
#include "chromeos/network/onc/onc_test_utils.h"
#include "chromeos/network/onc/onc_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace chromeos {
namespace onc {

class ONCValidatorTest : public ::testing::Test {
 public:
  // Validate |onc_object| with the given |signature|. The object is considered
  // to be managed if |managed_onc| is true. A strict validator is used if
  // |strict| is true. |onc_object| and the resulting repaired object of the
  // validation is stored, so that expectations can be checked afterwards using
  // one of the Expect* functions below.
  void Validate(bool strict,
                scoped_ptr<base::DictionaryValue> onc_object,
                const OncValueSignature* signature,
                bool managed_onc,
                ONCSource onc_source) {
    scoped_ptr<Validator> validator;
    if (strict) {
      // Create a strict validator that complains about every error.
      validator.reset(new Validator(true, true, true, managed_onc));
    } else {
      // Create a liberal validator that ignores or repairs non-critical errors.
      validator.reset(new Validator(false, false, false, managed_onc));
    }
    validator->SetOncSource(onc_source);
    original_object_ = onc_object.Pass();
    repaired_object_ = validator->ValidateAndRepairObject(signature,
                                                          *original_object_,
                                                          &validation_result_);
  }

  void ExpectValid() {
    EXPECT_EQ(Validator::VALID, validation_result_);
    EXPECT_TRUE(test_utils::Equals(original_object_.get(),
                                   repaired_object_.get()));
  }

  void ExpectRepairWithWarnings(
      const base::DictionaryValue& expected_repaired) {
    EXPECT_EQ(Validator::VALID_WITH_WARNINGS, validation_result_);
    EXPECT_TRUE(test_utils::Equals(&expected_repaired, repaired_object_.get()));
  }

  void ExpectInvalid() {
    EXPECT_EQ(Validator::INVALID, validation_result_);
    EXPECT_EQ(NULL, repaired_object_.get());
  }

 private:
  Validator::Result validation_result_;
  scoped_ptr<const base::DictionaryValue> original_object_;
  scoped_ptr<const base::DictionaryValue> repaired_object_;
};

namespace {

struct OncParams {
  // |location_of_object| is a string to identify the object to be tested. It
  // may be used as a filename or as a dictionary key.
  OncParams(const std::string& location_of_object,
            const OncValueSignature* onc_signature,
            bool is_managed_onc,
            ONCSource onc_source = ONC_SOURCE_NONE)
      : location(location_of_object),
        signature(onc_signature),
        is_managed(is_managed_onc),
        onc_source(onc_source) {
  }

  std::string location;
  const OncValueSignature* signature;
  bool is_managed;
  ONCSource onc_source;
};

::std::ostream& operator<<(::std::ostream& os, const OncParams& onc) {
  return os << "(" << onc.location << ", " << onc.signature << ", "
            << (onc.is_managed ? "managed" : "unmanaged") << ", "
            << GetSourceAsString(onc.onc_source) << ")";
}

}  // namespace

// Ensure that the constant |kEmptyUnencryptedConfiguration| describes a valid
// ONC toplevel object.
TEST_F(ONCValidatorTest, EmptyUnencryptedConfiguration) {
  Validate(true, ReadDictionaryFromJson(kEmptyUnencryptedConfiguration),
           &kToplevelConfigurationSignature, false, ONC_SOURCE_NONE);
  ExpectValid();
}

// This test case is about validating valid ONC objects without any errors. Both
// the strict and the liberal validator accept the object.
class ONCValidatorValidTest : public ONCValidatorTest,
                              public ::testing::WithParamInterface<OncParams> {
};

TEST_P(ONCValidatorValidTest, StrictValidationValid) {
  OncParams onc = GetParam();
  Validate(true, test_utils::ReadTestDictionary(onc.location), onc.signature,
           onc.is_managed, onc.onc_source);
  ExpectValid();
}

TEST_P(ONCValidatorValidTest, LiberalValidationValid) {
  OncParams onc = GetParam();
  Validate(false, test_utils::ReadTestDictionary(onc.location), onc.signature,
           onc.is_managed, onc.onc_source);
  ExpectValid();
}

// The parameters are:
// OncParams(string: Filename of a ONC file that is to be validated,
//           OncValueSignature: signature of that ONC,
//           bool: true if the ONC is managed).
INSTANTIATE_TEST_CASE_P(
    ONCValidatorValidTest,
    ONCValidatorValidTest,
    ::testing::Values(OncParams("managed_toplevel1.onc",
                                &kToplevelConfigurationSignature,
                                true),
                      OncParams("managed_toplevel2.onc",
                                &kToplevelConfigurationSignature,
                                true),
                      // Check that at least one configuration is accepted for
                      // device policies.
                      OncParams("managed_toplevel_wifi_peap.onc",
                                &kToplevelConfigurationSignature,
                                true,
                                ONC_SOURCE_DEVICE_POLICY),
                      OncParams("toplevel_wifi_wpa_psk.onc",
                                &kToplevelConfigurationSignature,
                                false),
                      OncParams("encrypted.onc",
                                &kToplevelConfigurationSignature,
                                true),
                      OncParams("managed_vpn.onc",
                                &kNetworkConfigurationSignature,
                                true),
                      OncParams("ethernet.onc",
                                &kNetworkConfigurationSignature,
                                true),
                      OncParams("ethernet_with_eap.onc",
                                &kNetworkConfigurationSignature,
                                true),
                      OncParams("translation_of_shill_wifi_with_state.onc",
                                &kNetworkWithStateSignature,
                                false)));

namespace {

struct RepairParams {
  // Both arguments are strings to identify the object that is expected as the
  // validation result. They may either be used as filenames or as dictionary
  // keys.
  RepairParams(std::string strict_repaired,
               std::string liberal_repaired)
      : location_of_strict_repaired(strict_repaired),
        location_of_liberal_repaired(liberal_repaired) {
  }

  std::string location_of_strict_repaired;
  std::string location_of_liberal_repaired;
};

::std::ostream& operator<<(::std::ostream& os, const RepairParams& rp) {
  return os << "(" << rp.location_of_strict_repaired << ", "
            << rp.location_of_liberal_repaired << ")";
}

}  // namespace

// This test case is about validating ONC objects that contain errors which can
// be repaired (then the errors count as warnings). If a location of the
// expected repaired object is given, then it is checked that the validator
// (either strict or liberal) returns this repaired object and the result is
// VALID_WITH_WARNINGS. If the location is the empty string, then it is expected
// that the validator returns NULL and the result INVALID.
class ONCValidatorTestRepairable
    : public ONCValidatorTest,
      public ::testing::WithParamInterface<std::pair<OncParams,
                                                     RepairParams> > {
 public:
  // Load the common test data and return the dictionary at the field with
  // name |name|.
  scoped_ptr<base::DictionaryValue> GetDictionaryFromTestFile(
      const std::string &name) {
    scoped_ptr<const base::DictionaryValue> dict(
        test_utils::ReadTestDictionary("invalid_settings_with_repairs.json"));
    const base::DictionaryValue* onc_object = NULL;
    CHECK(dict->GetDictionary(name, &onc_object));
    return make_scoped_ptr(onc_object->DeepCopy());
  }
};

TEST_P(ONCValidatorTestRepairable, StrictValidation) {
  OncParams onc = GetParam().first;
  Validate(true, GetDictionaryFromTestFile(onc.location), onc.signature,
           onc.is_managed, onc.onc_source);
  std::string location_of_repaired =
      GetParam().second.location_of_strict_repaired;
  if (location_of_repaired.empty())
    ExpectInvalid();
  else
    ExpectRepairWithWarnings(*GetDictionaryFromTestFile(location_of_repaired));
}

TEST_P(ONCValidatorTestRepairable, LiberalValidation) {
  OncParams onc = GetParam().first;
  Validate(false, GetDictionaryFromTestFile(onc.location), onc.signature,
           onc.is_managed, onc.onc_source);
  std::string location_of_repaired =
      GetParam().second.location_of_liberal_repaired;
  if (location_of_repaired.empty())
    ExpectInvalid();
  else
    ExpectRepairWithWarnings(*GetDictionaryFromTestFile(location_of_repaired));
}

// The parameters for all test case instantations below are:
// OncParams(string: A fieldname in the dictionary from the file
//                   "invalid_settings_with_repairs.json". That nested
//                   dictionary will be tested.
//           OncValueSignature: signature of that ONC,
//           bool: true if the ONC is managed).
// RepairParams(string: A fieldname in the dictionary from the file
//                      "invalid_settings_with_repairs.json". That nested
//                      dictionary is the expected result from strict
//                      validation,
//              string: A fieldname in the dictionary from the file
//                      "invalid_settings_with_repairs.json". That nested
//                      dictionary is the expected result from liberal
//                      validation).

// Strict validator returns INVALID. Liberal validator repairs.
INSTANTIATE_TEST_CASE_P(
    StrictInvalidLiberalRepair,
    ONCValidatorTestRepairable,
    ::testing::Values(
         std::make_pair(OncParams("network-unknown-fieldname",
                                  &kNetworkConfigurationSignature,
                                  false),
                        RepairParams("", "network-repaired")),
         std::make_pair(OncParams("managed-network-unknown-fieldname",
                                  &kNetworkConfigurationSignature,
                                  true),
                        RepairParams("", "managed-network-repaired")),
         std::make_pair(OncParams("managed-network-unknown-recommended",
                                  &kNetworkConfigurationSignature,
                                  true),
                        RepairParams("", "managed-network-repaired")),
         std::make_pair(OncParams("managed-network-dict-recommended",
                                  &kNetworkConfigurationSignature,
                                  true),
                        RepairParams("", "managed-network-repaired")),
         std::make_pair(OncParams("network-missing-required",
                                  &kNetworkConfigurationSignature,
                                  false),
                        RepairParams("", "network-missing-required")),
         std::make_pair(OncParams("managed-network-missing-required",
                                  &kNetworkConfigurationSignature,
                                  true),
                        RepairParams("", "managed-network-missing-required")),
         // Ensure that state values from Shill aren't accepted as
         // configuration.
         std::make_pair(OncParams("network-state-field",
                                  &kNetworkConfigurationSignature,
                                  false),
                        RepairParams("", "network-repaired")),
         std::make_pair(OncParams("network-nested-state-field",
                                  &kNetworkConfigurationSignature,
                                  false),
                        RepairParams("",
                                     "network-nested-state-field-repaired")),
         std::make_pair(OncParams("toplevel-with-repairable-networks",
                                  &kToplevelConfigurationSignature,
                                  false,
                                  ONC_SOURCE_DEVICE_POLICY),
                        RepairParams("", "toplevel-with-repaired-networks"))));

// Strict and liberal validator repair identically.
INSTANTIATE_TEST_CASE_P(
    StrictAndLiberalRepairIdentically,
    ONCValidatorTestRepairable,
    ::testing::Values(
         std::make_pair(OncParams("toplevel-invalid-network",
                                  &kToplevelConfigurationSignature,
                                  false),
                        RepairParams("toplevel-repaired",
                                     "toplevel-repaired")),
         std::make_pair(OncParams("toplevel-invalid-network",
                                  &kToplevelConfigurationSignature,
                                  true),
                        RepairParams("toplevel-repaired",
                                     "toplevel-repaired")),
         // Ignore recommended arrays in unmanaged ONC.
         std::make_pair(OncParams("network-with-illegal-recommended",
                                  &kNetworkConfigurationSignature,
                                  false),
                        RepairParams("network-repaired", "network-repaired")),
         std::make_pair(OncParams("toplevel-with-vpn",
                                  &kToplevelConfigurationSignature,
                                  false,
                                  ONC_SOURCE_DEVICE_POLICY),
                        RepairParams("toplevel-empty", "toplevel-empty")),
         std::make_pair(OncParams("toplevel-with-server-and-ca-cert",
                                  &kToplevelConfigurationSignature,
                                  true,
                                  ONC_SOURCE_DEVICE_POLICY),
                        RepairParams("toplevel-server-and-ca-cert-dropped",
                                     "toplevel-server-and-ca-cert-dropped"))));

// Strict and liberal validator both repair, but with different results.
INSTANTIATE_TEST_CASE_P(
    StrictAndLiberalRepairDifferently,
    ONCValidatorTestRepairable,
    ::testing::Values(
         std::make_pair(OncParams("toplevel-with-nested-warning",
                                  &kToplevelConfigurationSignature,
                                  false),
                        RepairParams("toplevel-empty", "toplevel-repaired"))));

// Strict and liberal validator return both INVALID.
INSTANTIATE_TEST_CASE_P(
    StrictAndLiberalInvalid,
    ONCValidatorTestRepairable,
    ::testing::Values(
         std::make_pair(OncParams("network-unknown-value",
                                  &kNetworkConfigurationSignature, false),
                        RepairParams("", "")),
         std::make_pair(OncParams("managed-network-unknown-value",
                                  &kNetworkConfigurationSignature, true),
                        RepairParams("", "")),
         std::make_pair(OncParams("network-value-out-of-range",
                                  &kNetworkConfigurationSignature, false),
                        RepairParams("", "")),
         std::make_pair(OncParams("managed-network-value-out-of-range",
                                  &kNetworkConfigurationSignature, true),
                        RepairParams("", "")),
         std::make_pair(OncParams("network-wrong-type",
                                  &kNetworkConfigurationSignature, false),
                        RepairParams("", "")),
         std::make_pair(OncParams("managed-network-wrong-type",
                                  &kNetworkConfigurationSignature, true),
                        RepairParams("", "")),
         std::make_pair(OncParams("network-with-client-cert-pattern",
                                  &kNetworkConfigurationSignature, true,
                                  ONC_SOURCE_DEVICE_POLICY),
                        RepairParams("", ""))));

}  // namespace onc
}  // namespace chromeos
