// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package config_validator

import (
	"config"
	"errors"
	"math"
	"testing"
)

// makeValidReport returns a valid instance of config.ReportDefinition which
// can be modified to fail various validation checks for testing purposes.
func makeValidReport() *config.ReportDefinition {
	return makeValidReportWithNameAndType("the_report_name", config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS)
}

func makeValidReportWithType(t config.ReportDefinition_ReportType) *config.ReportDefinition {
	return makeValidReportWithNameAndType("the_report_name", t)
}

func makeValidReportWithName(name string) *config.ReportDefinition {
	return makeValidReportWithNameAndType(name, config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS)
}

func makeValidReportWithNameAndType(name string, t config.ReportDefinition_ReportType) *config.ReportDefinition {
	return &config.ReportDefinition{
		Id:               10,
		ReportName:       name,
		ReportType:       t,
		PrivacyLevel:     config.ReportDefinition_NO_ADDED_PRIVACY,
		PrivacyMechanism: config.ReportDefinition_DE_IDENTIFICATION,
	}
}

// Given a metric type |mt|, returns a valid report type for that metric type.
// Prefers to return a non-histogram report type if the given metric type supports
// one, to aid in checking where int_buckets get set in tests.
func getMatchingReportType(mt config.MetricDefinition_MetricType) config.ReportDefinition_ReportType {
	switch mt {
	case config.MetricDefinition_OCCURRENCE:
		return config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS
	case config.MetricDefinition_INTEGER:
		return config.ReportDefinition_FLEETWIDE_MEANS
	case config.MetricDefinition_INTEGER_HISTOGRAM:
		return config.ReportDefinition_FLEETWIDE_HISTOGRAMS
	case config.MetricDefinition_STRING:
		return config.ReportDefinition_STRING_COUNTS
	}

	return config.ReportDefinition_REPORT_TYPE_UNSET
}

// Test that makeValidReport returns a valid report.
func TestValidateMakeValidReport(t *testing.T) {
	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	r := makeValidReport()
	if err := validateReportDefinition(m, r); err != nil {
		t.Errorf("Rejected valid report: %v", err)
	}
}

func TestDifferentReportId(t *testing.T) {
	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	r := makeValidReport()
	r.Id += 1

	if err := validateReportDefinition(m, r); err != nil {
		t.Error("Reject report with different report id.")
	}
}

func TestValidateReportHasNoAppVersionField(t *testing.T) {
	r := makeValidReport()

	r.SystemProfileField = []config.SystemProfileField{
		config.SystemProfileField_CHANNEL, config.SystemProfileField_APP_VERSION}
	if err := validateReportHasNoAppVersionField(r); err == nil {
		t.Error("Did not detect app_version field.")
	}

	r.SystemProfileField = []config.SystemProfileField{
		config.SystemProfileField_CHANNEL}
	if err := validateReportHasNoAppVersionField(r); err != nil {
		t.Error("Detected app_version field - although there was none.")
	}
}

func TestNoAppVersionFieldOnFuchsiaErrorCase(t *testing.T) {
	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	r := makeValidReport()

	m.CustomerId = math.MaxInt32
	r.SystemProfileField = []config.SystemProfileField{
		config.SystemProfileField_APP_VERSION}
	if err := validateReportDefinitionForMetric(m, r); err == nil {
		t.Error("Accepted report with set app_version field on Fuchsia.")
	}
}

func TestNoAppVersionFieldOnFuchsiaNoFuchsiaCase(t *testing.T) {
	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	r := makeValidReport()

	m.CustomerId = 3
	r.SystemProfileField = []config.SystemProfileField{
		config.SystemProfileField_APP_VERSION}
	if err := validateReportDefinitionForMetric(m, r); err != nil {
		t.Error("Didn't accept app_version field, although it wasn't Fuchsia.")
	}
}

func TestNoAppVersionFieldOnFuchsiaNoAppVersionField(t *testing.T) {
	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	r := makeValidReport()

	m.CustomerId = 1
	r.SystemProfileField = []config.SystemProfileField{
		config.SystemProfileField_CHANNEL}
	if err := validateReportDefinitionForMetric(m, r); err != nil {
		t.Error("Did not accept ordinary report.")
	}
}

func TestValidateInvalidName(t *testing.T) {
	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	r := makeValidReportWithName("_invalid_name")

	if err := validateReportDefinition(m, r); err == nil {
		t.Error("Accepted report with invalid name.")
	}
}

func TestValidateZeroReportId(t *testing.T) {
	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	r := makeValidReportWithName("NRaMinLNcqiYmgEypLLVGnXymNpxJzqabtbbjLycCMEohvVzZtAYpah")
	r.Id = 0

	if err := validateReportDefinition(m, r); err == nil {
		t.Error("Accepted report with 0 id.")
	}
}

func TestValidateUnsetReportType(t *testing.T) {
	if err := validateReportType(config.MetricDefinition_OCCURRENCE, config.ReportDefinition_REPORT_TYPE_UNSET); err == nil {
		t.Error("Accepted report with no report type set.")
	}
}

func TestValidatePoissonFields(t *testing.T) {
	r := makeValidReport()
	r.ReportType = config.ReportDefinition_UNIQUE_DEVICE_COUNTS

	r.PrivacyLevel = config.ReportDefinition_NO_ADDED_PRIVACY
	r.PoissonMean = 1.0
	if err := validatePoissonFields(r); err == nil {
		t.Error("Accepted report definition with `poisson_mean` set but with NO_ADDED_PRIVACY privacy level")
	}

	r.PrivacyLevel = config.ReportDefinition_HIGH_PRIVACY
	r.PoissonMean = 0.0
	if err := validatePoissonFields(r); err == nil {
		t.Error("Accepted report definition with a nontrivial privacy level, but without `poisson_mean`")
	}

	r.PoissonMean = -1.0
	if err := validatePoissonFields(r); err == nil {
		t.Error("Accepted report definition with a nontrivial privacy level, but negative `poisson_mean`")
	}

	r.PoissonMean = 1.0
	if err := validatePoissonFields(r); err == nil {
		t.Error("Accepted report definition with a nontrivial privacy level, but `num_index_points` unset")
	}

	r.NumIndexPoints = 1
	if err := validatePoissonFields(r); err != nil {
		t.Error("Rejected report definition with a nontrivial privacy level and valid privacy settings")
	}

	stringSketchParams := config.StringSketchParameters{
		NumCellsPerHash: 10,
		NumHashes:       5,
	}

	r.ReportType = config.ReportDefinition_STRING_COUNTS
	if err := validatePoissonFields(r); err == nil {
		t.Error("Accepted STRING_COUNTS report definition with a nontrivial privacy level, but `string_sketch_params` unset")
	}
	r.ReportType = config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS
	if err := validatePoissonFields(r); err == nil {
		t.Error("Accepted UNIQUE_DEVICE_STRING_COUNTS report definition with a nontrivial privacy level, but `string_sketch_params` unset")
	}

	r.StringSketchParams = &stringSketchParams
	r.ReportType = config.ReportDefinition_STRING_COUNTS
	if err := validatePoissonFields(r); err != nil {
		t.Error("Rejected STRING_COUNTS report definition with a nontrivial privacy level and valid privacy settings")
	}
	r.ReportType = config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS
	if err := validatePoissonFields(r); err != nil {
		t.Error("Rejected UNIQUE_DEVICE_STRING_COUTNS report definition with a nontrivial privacy level and valid privacy settings")
	}
}

func TestValidateMinValueMaxValueNoAddedPrivacy(t *testing.T) {
	var reportTypes = []config.ReportDefinition_ReportType{
		config.ReportDefinition_UNIQUE_DEVICE_COUNTS,
		config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS,
		config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS,
		config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS,
		config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS,
		config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS,
		config.ReportDefinition_FLEETWIDE_HISTOGRAMS,
		config.ReportDefinition_FLEETWIDE_MEANS,
		config.ReportDefinition_STRING_COUNTS,
		config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS,
	}
	type args struct {
		minValue int64
		maxValue int64
	}
	var tests = []struct {
		input args
		valid bool
	}{
		// Valid reports: no added privacy, no bounds set
		{args{0, 0}, true},
		// Invalid reports: no added privacy, at least one of min_value and max_value set
		{args{0, 1}, false},
		{args{1, 0}, false},
		{args{1, 1}, false},
	}
	for _, reportType := range reportTypes {
		for _, test := range tests {
			r := makeValidReportWithType(reportType)
			r.PrivacyLevel = config.ReportDefinition_NO_ADDED_PRIVACY
			r.MinValue = test.input.minValue
			r.MaxValue = test.input.maxValue
			err := validateMinValueMaxValue(r)

			if test.valid && err != nil {
				t.Errorf("rejected valid report with type %v and (min_value, max_value) = %v error: %v",
					reportType, test.input, err)
			} else if !test.valid && err == nil {
				t.Errorf("accepted invalid report with type %v and (min_value, max_value) = %v",
					reportType, test.input)
			}
		}
	}
}

func TestValidateMinValueMaxValueWithAddedPrivacy(t *testing.T) {
	var required = []config.ReportDefinition_ReportType{
		config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS,
		config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS,
		config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS,
		config.ReportDefinition_FLEETWIDE_MEANS,
	}
	var notAllowed = []config.ReportDefinition_ReportType{
		config.ReportDefinition_UNIQUE_DEVICE_COUNTS,
		config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS,
		config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS,
		config.ReportDefinition_FLEETWIDE_HISTOGRAMS,
		config.ReportDefinition_STRING_COUNTS,
		config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS,
	}
	type args struct {
		reportTypes []config.ReportDefinition_ReportType
		minValue    int64
		maxValue    int64
	}
	var tests = []struct {
		input args
		valid bool
	}{
		// Valid reports: min value and max value should not be set
		{args{notAllowed, 0, 0}, true},
		// Valid reports: at least one of min value and max value should be set
		{args{required, 0, 1}, true},
		{args{required, -1, 1}, true},
		{args{required, 1, 1}, true},
		// Invalid reports: min value and max value should not be set
		{args{notAllowed, 0, 1}, false},
		{args{notAllowed, -1, 0}, false},
		// Invalid reports: at least one of min value and max value should be set
		{args{required, 0, 0}, false},
		// Invalid reports: min value is larger than max value
		{args{required, 2, 1}, false},
	}
	for _, test := range tests {
		for _, reportType := range test.input.reportTypes {
			r := makeValidReportWithType(reportType)
			r.PrivacyLevel = config.ReportDefinition_LOW_PRIVACY
			r.MinValue = test.input.minValue
			r.MaxValue = test.input.maxValue
			err := validateMinValueMaxValue(r)

			if test.valid && err != nil {
				t.Errorf("rejected valid report of type %v with error: %v", reportType, err)
			} else if !test.valid && err == nil {
				t.Errorf("accepted invalid report of type %v and (min_value, max_value) = (%d, %d)",
					reportType, test.input.minValue, test.input.maxValue)
			}
		}
	}
}

func TestValidateMaxCountNoAddedPrivacy(t *testing.T) {
	var reportTypes = []config.ReportDefinition_ReportType{
		config.ReportDefinition_UNIQUE_DEVICE_COUNTS,
		config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS,
		config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS,
		config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS,
		config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS,
		config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS,
		config.ReportDefinition_FLEETWIDE_HISTOGRAMS,
		config.ReportDefinition_FLEETWIDE_MEANS,
		config.ReportDefinition_STRING_COUNTS,
		config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS,
	}
	var tests = []struct {
		maxCount uint64
		valid    bool
	}{
		// Valid reports: no added privacy, no bounds set
		{0, true},
		// Invalid reports: no added privacy, max_count set
		{1, false},
	}
	for _, reportType := range reportTypes {
		for _, test := range tests {
			r := makeValidReportWithType(reportType)
			r.PrivacyLevel = config.ReportDefinition_NO_ADDED_PRIVACY
			r.MaxCount = test.maxCount
			err := validateMaxCount(r)

			if test.valid && err != nil {
				t.Errorf("rejected valid report with type %v and max_count = %d error: %v",
					reportType, test.maxCount, err)
			} else if !test.valid && err == nil {
				t.Errorf("accepted invalid report with type %v and max_count = %d",
					reportType, test.maxCount)
			}
		}
	}
}

func TestValidateMaxCountWithAddedPrivacy(t *testing.T) {
	var required = []config.ReportDefinition_ReportType{
		config.ReportDefinition_FLEETWIDE_HISTOGRAMS,
		config.ReportDefinition_FLEETWIDE_MEANS,
		config.ReportDefinition_STRING_COUNTS,
	}
	var notAllowed = []config.ReportDefinition_ReportType{
		config.ReportDefinition_UNIQUE_DEVICE_COUNTS,
		config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS,
		config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS,
		config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS,
		config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS,
		config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS,
		config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS,
	}
	type args struct {
		reportTypes []config.ReportDefinition_ReportType
		maxCount    uint64
	}
	var tests = []struct {
		input args
		valid bool
	}{
		// Valid reports: max count should be set
		{args{required, 1}, true},
		// Valid reports: max count should not be set
		{args{notAllowed, 0}, true},
		// Valid reports: max count should be set
		{args{required, 1}, true},
		// Invalid reports: max count should not be set
		{args{notAllowed, 1}, false},
		// Invalid reports: max count should be set
		{args{required, 0}, false},
	}
	for _, test := range tests {
		for _, reportType := range test.input.reportTypes {
			r := makeValidReportWithType(reportType)
			r.PrivacyLevel = config.ReportDefinition_LOW_PRIVACY
			r.MaxCount = test.input.maxCount
			err := validateMaxCount(r)

			if test.valid && err != nil {
				t.Errorf("rejected valid report of type %v with error: %v", reportType, err)
			} else if !test.valid && err == nil {
				t.Errorf("accepted invalid report of type %v and max_count = %d",
					reportType, test.input.maxCount)
			}
		}
	}
}

// Test that int_buckets is not set if the report type is STRING_COUNTS.
func TestValidateReportDefinitionForStringCounts(t *testing.T) {
	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	r := makeValidReport()
	r.ReportType = config.ReportDefinition_STRING_COUNTS
	r.PrivacyLevel = config.ReportDefinition_NO_ADDED_PRIVACY
	r.StringBufferMax = 10

	if err := validateReportDefinition(m, r); err != nil {
		t.Errorf("Failed validation for valid report of type STRING_COUNTS: %v", err)
	}

	r.IntBuckets = &config.IntegerBuckets{}
	if err := validateReportDefinition(m, r); err == nil {
		t.Error("Accepted report definition of type STRING_COUNTS with int_buckets specified.")
	}
}

// Test that int_buckets is not set if the report type is UNIQUE_DEVICE_STRING_COUNTS.
func TestValidateReportDefitionForUniqueDeviceStringCounts(t *testing.T) {
	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	r := makeValidReport()
	r.ReportType = config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS
	r.PrivacyLevel = config.ReportDefinition_NO_ADDED_PRIVACY
	r.LocalAggregationPeriod = config.WindowSize_WINDOW_1_DAY
	r.StringBufferMax = 10

	if err := validateReportDefinition(m, r); err != nil {
		t.Errorf("Failed validation for valid report of type UNIQUE_DEVICE_STRING_COUNTS: %v", err)
	}

	r.IntBuckets = &config.IntegerBuckets{}
	if err := validateReportDefinition(m, r); err == nil {
		t.Errorf("Accepted report definition of type UNIQUE_DEVICE_STRING_COUNTS with int_buckets specified.")
	}
}

func TestValidateLocalAggregationPeriod(t *testing.T) {
	dailyReportTypes := []config.ReportDefinition_ReportType{
		config.ReportDefinition_UNIQUE_DEVICE_COUNTS,
		config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS,
		config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS,
		config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS,
	}
	hourlyReportTypes := []config.ReportDefinition_ReportType{
		config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS,
		config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS,
		config.ReportDefinition_FLEETWIDE_HISTOGRAMS,
		config.ReportDefinition_FLEETWIDE_MEANS,
		config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS,
		config.ReportDefinition_STRING_COUNTS,
	}

	for _, reportType := range dailyReportTypes {
		r := makeValidReportWithType(reportType)

		if err := validateLocalAggregationPeriod(r); err == nil {
			t.Error("Accepted daily report with no local_aggregation_period")
		}

		r.LocalAggregationPeriod = config.WindowSize_WINDOW_1_DAY
		if err := validateLocalAggregationPeriod(r); err != nil {
			t.Errorf("Rejected daily report with valid local_aggregation_period: %v", err)
		}
	}

	for _, reportType := range hourlyReportTypes {
		r := makeValidReportWithType(reportType)

		r.LocalAggregationPeriod = config.WindowSize_WINDOW_1_DAY
		if err := validateLocalAggregationPeriod(r); err == nil {
			t.Error("Accepted hourly report with local_aggregation_period")
		}

		r.LocalAggregationPeriod = config.WindowSize_UNSET
		if err := validateLocalAggregationPeriod(r); err != nil {
			t.Errorf("Rejected hourly report with no local_aggregation_period: %v", err)
		}
	}
}

func TestValidateLocalAggregationProcedure(t *testing.T) {
	intLocalAggregationProcedureTypes := []config.ReportDefinition_ReportType{
		config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS,
		config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS,
		config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS,
		config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS,
	}

	for _, reportType := range intLocalAggregationProcedureTypes {
		m := makeValidMetric(config.MetricDefinition_INTEGER)
		r := makeValidReportWithType(reportType)

		if err := validateLocalAggregationProcedure(m, r); err == nil {
			t.Error("Accepted invalid report with no local_aggregation_procedure")
		}

		r.LocalAggregationProcedure = config.ReportDefinition_AT_LEAST_ONCE
		if err := validateLocalAggregationProcedure(m, r); err == nil {
			t.Error("Accepted report with invalid local_aggregation_procedure")
		}

		r.LocalAggregationProcedure = config.ReportDefinition_MEDIAN
		if err := validateLocalAggregationProcedure(m, r); err != nil {
			t.Errorf("Rejected report with valid local_aggregation_procedure: %v", err)
		}

		r.LocalAggregationProcedure = config.ReportDefinition_PERCENTILE_N
		if err := validateLocalAggregationProcedure(m, r); err == nil {
			t.Error("Accepted PERCENTILE_N report with no local_aggregation_procedure_percentile_n set")
		}
		r.LocalAggregationProcedurePercentileN = 110
		if err := validateLocalAggregationProcedure(m, r); err == nil {
			t.Error("Accepted PERCENTILE_N report with invalid local_aggregation_procedure_percentile_n set")
		}
		r.LocalAggregationProcedurePercentileN = 5
		if err := validateLocalAggregationProcedure(m, r); err != nil {
			t.Errorf("Rejected PERCENTILE_N report with valid local_aggregation_procedure_percentile_n: %v", err)
		}

		m = makeValidMetric(config.MetricDefinition_OCCURRENCE)
		if err := validateLocalAggregationProcedure(m, r); err == nil {
			t.Error("Accepted daily report with no local_aggregation_procedure")
		}

		r.LocalAggregationProcedure = config.ReportDefinition_LOCAL_AGGREGATION_PROCEDURE_UNSET
		if err := validateLocalAggregationProcedure(m, r); err != nil {
			t.Errorf("Rejected daily report with valid local_aggregation_procedure: %v", err)
		}
	}

	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	r := makeValidReportWithType(config.ReportDefinition_UNIQUE_DEVICE_COUNTS)
	if err := validateLocalAggregationProcedure(m, r); err == nil {
		t.Error("Accepted invalid report with no local_aggregation_procedure")
	}
	r.LocalAggregationProcedure = config.ReportDefinition_MEDIAN
	if err := validateLocalAggregationProcedure(m, r); err == nil {
		t.Error("Accepted report with invalid local_aggregation_procedure")
	}
	r.LocalAggregationProcedure = config.ReportDefinition_AT_LEAST_ONCE
	if err := validateLocalAggregationProcedure(m, r); err != nil {
		t.Errorf("Rejected report with valid local_aggregation_procedure: %v", err)
	}

	r.LocalAggregationProcedure = config.ReportDefinition_SELECT_FIRST
	r.EventVectorBufferMax = 1
	if err := validateLocalAggregationProcedure(m, r); err != nil {
		t.Errorf("Rejected report with valid event_vector_buffer_max config: %v", err)
	}

	r.EventVectorBufferMax = 100
	if err := validateLocalAggregationProcedure(m, r); err == nil {
		t.Errorf("Accepted report with invalid event_vector_buffer_max config")
	}

	r = makeValidReportWithType(config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS)
	r.LocalAggregationProcedure = config.ReportDefinition_AT_LEAST_ONCE
	if err := validateLocalAggregationProcedure(m, r); err == nil {
		t.Error("Accepted report with unnecessary local_aggregation_procedure")
	}
}

func TestValidateExpeditedSending(t *testing.T) {
	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	r := makeValidReportWithType(config.ReportDefinition_UNIQUE_DEVICE_COUNTS)
	r.ExpeditedSending = true
	r.LocalAggregationProcedure = config.ReportDefinition_SELECT_MOST_COMMON
	r.PrivacyLevel = config.ReportDefinition_NO_ADDED_PRIVACY
	if err := validateExpeditedSending(m, r); err == nil {
		t.Error("Accepted report with invalid local_aggregation_procedure for expedited_sending")
	}
	r.LocalAggregationProcedure = config.ReportDefinition_AT_LEAST_ONCE
	if err := validateExpeditedSending(m, r); err != nil {
		t.Errorf("Rejected report with expedited_sending and valid local_aggregation_procedure: %v", err)
	}
	r.LocalAggregationProcedure = config.ReportDefinition_SELECT_FIRST
	if err := validateExpeditedSending(m, r); err != nil {
		t.Errorf("Rejected report with expedited_sending and valid local_aggregation_procedure: %v", err)
	}
	r.PrivacyLevel = config.ReportDefinition_LOW_PRIVACY
	if err := validateExpeditedSending(m, r); err == nil {
		t.Error("Accepted report with invalid privacy_level for expedited_sending")
	}

	r = makeValidReportWithType(config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS)
	r.ExpeditedSending = true
	r.LocalAggregationProcedure = config.ReportDefinition_AT_LEAST_ONCE
	if err := validateExpeditedSending(m, r); err == nil {
		t.Error("Accepted report with invalid type for expedited_sending")
	}
	r.ExpeditedSending = false
	r.LocalAggregationProcedure = config.ReportDefinition_SELECT_MOST_COMMON
	if err := validateExpeditedSending(m, r); err != nil {
		t.Errorf("Rejected report with expedited_sending unset: %v", err)
	}

	m = makeValidMetric(config.MetricDefinition_STRING)
	r = makeValidReportWithType(config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS)
	r.ExpeditedSending = true
	r.LocalAggregationProcedure = config.ReportDefinition_LOCAL_AGGREGATION_PROCEDURE_UNSET
	r.PrivacyLevel = config.ReportDefinition_NO_ADDED_PRIVACY
	if err := validateExpeditedSending(m, r); err != nil {
		t.Errorf("Rejected report with expedited_sending and valid report type: %v", err)
	}
}

func TestValidateMaxReleaseStage(t *testing.T) {
	// Default valid metric uses DEBUG max_release_stage.
	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	r := makeValidReportWithType(config.ReportDefinition_UNIQUE_DEVICE_COUNTS)
	if err := validateMaxReleaseStage(m, r); err != nil {
		t.Errorf("Rejected report with no max_release_stage: %v", err)
	}
	r.MaxReleaseStage = config.ReleaseStage_DEBUG
	if err := validateMaxReleaseStage(m, r); err != nil {
		t.Errorf("Rejected report with the same max_release_stage as the metric: %v", err)
	}
	r.MaxReleaseStage = config.ReleaseStage_FISHFOOD
	if err := validateMaxReleaseStage(m, r); err == nil {
		t.Error("Accepted report with max_release_stage later than in the metric")
	}
	m.MetaData.MaxReleaseStage = config.ReleaseStage_FISHFOOD
	if err := validateMaxReleaseStage(m, r); err != nil {
		t.Errorf("Rejected report with the same max_release_stage as the metric: %v", err)
	}
	m.MetaData.MaxReleaseStage = config.ReleaseStage_DOGFOOD
	if err := validateMaxReleaseStage(m, r); err != nil {
		t.Errorf("Rejected report with max_release_stage earlier than the metric: %v", err)
	}
}

func TestValidateExemptFromConsent(t *testing.T) {
	r := makeValidReportWithType(config.ReportDefinition_UNIQUE_DEVICE_COUNTS)
	r.ExemptFromConsent = true
	r.PrivacyLevel = config.ReportDefinition_NO_ADDED_PRIVACY
	if err := validateExemptFromConsent(r); err == nil {
		t.Error("Accepted report with no differential privacy and exempt_from_consent set")
	}
	r.PrivacyLevel = config.ReportDefinition_LOW_PRIVACY
	if err := validateExemptFromConsent(r); err != nil {
		t.Errorf("Rejected report with valid exempt_from_consent: %v", err)
	}
}

func TestValidateMaxPrivateIndex(t *testing.T) {
	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	r := makeValidReportWithType(config.ReportDefinition_UNIQUE_DEVICE_COUNTS)
	r.PrivacyLevel = config.ReportDefinition_NO_ADDED_PRIVACY
	if err := validateMaxPrivateIndex(m, r); err != nil {
		t.Errorf("Rejected report with valid max private index: %v", err)
	}
	r.PrivacyLevel = config.ReportDefinition_HIGH_PRIVACY
	if err := validateMaxPrivateIndex(m, r); err != nil {
		t.Errorf("Rejected private UNIQUE_DEVICE_COUNTS report with valid max private index: %v", err)
	}
	m.MetricDimensions = append(m.MetricDimensions, &config.MetricDefinition_MetricDimension{
		Dimension:    "Dimension with lots of event codes",
		MaxEventCode: math.MaxInt32 + 1, // > INT32_MAX
	})
	if err := validateMaxPrivateIndex(m, r); err == nil {
		t.Error("Accepted private UNIQUE_DEVICE_COUNTS report with too many private indices")
	}

	m = makeValidMetric(config.MetricDefinition_OCCURRENCE)
	m.MetricDimensions = append(m.MetricDimensions, &config.MetricDefinition_MetricDimension{
		Dimension:    "Dimension with lots of event codes",
		MaxEventCode: 1000,
	})
	r = makeValidReportWithType(config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS)
	r.PrivacyLevel = config.ReportDefinition_HIGH_PRIVACY
	r.NumIndexPoints = 10
	if err := validateMaxPrivateIndex(m, r); err != nil {
		t.Errorf("Rejected private FLEETWIDE_OCCURRENCE_COUNTS report with valid max private index: %v", err)
	}
	r.NumIndexPoints = math.MaxInt32 / 10 // * 1,000 * 10 will be > INT32_MAX
	if err := validateMaxPrivateIndex(m, r); err == nil {
		t.Error("Accepted private FLEETWIDE_OCCURRENCE_COUNTS report with too many private indices")
	}

	m = makeValidMetric(config.MetricDefinition_INTEGER)
	m.MetricDimensions = append(m.MetricDimensions, &config.MetricDefinition_MetricDimension{
		Dimension:    "Dimension with lots of event codes",
		MaxEventCode: 1000,
	})
	r = makeValidReportWithType(config.ReportDefinition_FLEETWIDE_MEANS)
	r.PrivacyLevel = config.ReportDefinition_HIGH_PRIVACY
	r.NumIndexPoints = 10
	if err := validateMaxPrivateIndex(m, r); err != nil {
		t.Errorf("Rejected private FLEETWIDE_MEANS report with valid max private index: %v", err)
	}
	r.NumIndexPoints = math.MaxInt32 / 100 // * 1,000 * 10 will be > INT32_MAX
	if err := validateMaxPrivateIndex(m, r); err == nil {
		t.Error("Accepted private FLEETWIDE_MEANS report with too many private indices")
	}

	r = makeValidReportWithType(config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS)
	r.PrivacyLevel = config.ReportDefinition_HIGH_PRIVACY
	r.IntBuckets = &config.IntegerBuckets{
		Buckets: &config.IntegerBuckets_Linear{
			Linear: &config.LinearIntegerBuckets{
				NumBuckets: 1000,
			},
		},
	}
	if err := validateMaxPrivateIndex(m, r); err != nil {
		t.Errorf("Rejected private UNIQUE_DEVICE_HISTOGRAMS report with valid max private index: %v", err)
	}
	r.IntBuckets.GetLinear().NumBuckets = 10000000 // 10,000,000 * 1,000 > INT32_MAX
	if err := validateMaxPrivateIndex(m, r); err == nil {
		t.Error("Accepted private UNIQUE_DEVICE_HISTOGRAMS report with too many private indices")
	}

	m = makeValidMetric(config.MetricDefinition_INTEGER_HISTOGRAM)
	m.MetricDimensions = append(m.MetricDimensions, &config.MetricDefinition_MetricDimension{
		Dimension:    "Dimension with lots of event codes",
		MaxEventCode: 1000,
	})
	m.IntBuckets = &config.IntegerBuckets{
		Buckets: &config.IntegerBuckets_Linear{
			Linear: &config.LinearIntegerBuckets{
				NumBuckets: 1000,
			},
		},
	}
	r = makeValidReportWithType(config.ReportDefinition_FLEETWIDE_HISTOGRAMS)
	r.PrivacyLevel = config.ReportDefinition_HIGH_PRIVACY
	r.NumIndexPoints = 1000
	if err := validateMaxPrivateIndex(m, r); err != nil {
		t.Errorf("Rejected private FLEETWIDE_HISTOGRAMS report with valid max private index: %v", err)
	}
	m.IntBuckets.GetLinear().NumBuckets = 10000 // 10,000 * 1,000 * 1,000 > INT32_MAX
	if err := validateMaxPrivateIndex(m, r); err == nil {
		t.Error("Accepted private FLEETWIDE_HISTOGRAMS report with too many private indices")
	}

	m = makeValidMetric(config.MetricDefinition_STRING)
	m.MetricDimensions = append(m.MetricDimensions, &config.MetricDefinition_MetricDimension{
		Dimension:    "Dimension with lots of event codes",
		MaxEventCode: 1000,
	})
	r = makeValidReportWithType(config.ReportDefinition_STRING_COUNTS)
	r.PrivacyLevel = config.ReportDefinition_HIGH_PRIVACY
	if err := validateMaxPrivateIndex(m, r); err != nil {
		t.Errorf("Rejected private STRING_COUNTS report with valid max private index: %v", err)
	}
	m.MetricDimensions = append(m.MetricDimensions, &config.MetricDefinition_MetricDimension{
		Dimension:    "Dimension with lots of event codes",
		MaxEventCode: 1000000, // 1,000,000 * 1,000 * 50 (string count-min constants) will be > INT32_MAX
	})
	if err := validateMaxPrivateIndex(m, r); err == nil {
		t.Error("Accepted private STRING_COUNTS report with too many private indices")
	}
}

func TestValidateNoHourlyReports(t *testing.T) {
	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	dailyReportTypes := []config.ReportDefinition_ReportType{
		config.ReportDefinition_UNIQUE_DEVICE_COUNTS,
		config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS,
		config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS,
		config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS,
	}
	hourlyReportTypes := []config.ReportDefinition_ReportType{
		config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS,
		config.ReportDefinition_FLEETWIDE_HISTOGRAMS,
		config.ReportDefinition_FLEETWIDE_MEANS,
		config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS,
		config.ReportDefinition_STRING_COUNTS,
	}

	for _, reportType := range dailyReportTypes {
		r := makeValidReportWithType(reportType)
		if err := validateNoHourlyReports(m, r); err != nil {
			t.Errorf("Rejected daily report: %v", err)
		}
	}

	for _, reportType := range hourlyReportTypes {
		r := makeValidReportWithType(reportType)
		if err := validateNoHourlyReports(m, r); err == nil {
			t.Error("Accepted hourly report")
		}
	}

	// Test FLEETWIDE_OCCURRENCE_COUNTS, which may define a non-hourly reporting
	// interval.
	r := makeValidReportWithType(config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS)
	// Test unset reporting interval.
	err := validateNoHourlyReports(m, r)
	if err == nil {
		t.Error("Accepted hourly FLEETWIDE_OCCURRENCE_COUNTS report with default reporting interval")
	}
	if !errors.Is(err, errIllegalHourlyReport) {
		t.Errorf("Incorrect error return type: %v", err)
	}

	// Test HOURS_1 reporting interval.
	r.ReportingInterval = config.ReportDefinition_HOURS_1
	err = validateNoHourlyReports(m, r)
	if err == nil {
		t.Error("Accepted hourly FLEETWIDE_OCCURRENCE_COUNTS report with hourly reporting interval")
	}
	if !errors.Is(err, errIllegalHourlyReport) {
		t.Errorf("Incorrect error return type: %v", err)
	}

	// Test DAYS_1 reporting interval.
	r.ReportingInterval = config.ReportDefinition_DAYS_1
	if err := validateNoHourlyReports(m, r); err != nil {
		t.Errorf("Rejected daily FLEETWIDE_OCCURRENCE_COUNTS report with daily reporting interval: %v", err)
	}

	// Test STRING_COUNTS, which may define a non-hourly reporting
	// interval.
	r = makeValidReportWithType(config.ReportDefinition_STRING_COUNTS)
	// Test unset reporting interval.
	err = validateNoHourlyReports(m, r)
	if err == nil {
		t.Error("Accepted hourly STRING_COUNTS report with default reporting interval")
	}
	if !errors.Is(err, errIllegalHourlyReport) {
		t.Errorf("Incorrect error return type: %v", err)
	}

	// Test HOURS_1 reporting interval.
	r.ReportingInterval = config.ReportDefinition_HOURS_1
	err = validateNoHourlyReports(m, r)
	if err == nil {
		t.Error("Accepted hourly STRING_COUNTS report with hourly reporting interval")
	}
	if !errors.Is(err, errIllegalHourlyReport) {
		t.Errorf("Incorrect error return type: %v", err)
	}

	// Test DAYS_1 reporting interval.
	r.ReportingInterval = config.ReportDefinition_DAYS_1
	if err := validateNoHourlyReports(m, r); err != nil {
		t.Errorf("Rejected daily STRING_COUNTS report with daily reporting interval: %v", err)
	}
}

func TestValidateEnabledReportingInterval(t *testing.T) {
	unsupportedReportTypes := []config.ReportDefinition_ReportType{
		config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS,
		config.ReportDefinition_FLEETWIDE_HISTOGRAMS,
		config.ReportDefinition_FLEETWIDE_MEANS,
		config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS,
		config.ReportDefinition_UNIQUE_DEVICE_COUNTS,
		config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS,
		config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS,
		config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS,
	}

	supportedReportTypes := []config.ReportDefinition_ReportType{
		config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS,
		config.ReportDefinition_STRING_COUNTS,
	}

	reportingIntervalValues := []config.ReportDefinition_ReportingInterval{
		config.ReportDefinition_HOURS_1,
		config.ReportDefinition_DAYS_1,
	}

	for _, reportType := range supportedReportTypes {
		// Check supported report types.
		r := makeValidReportWithType(reportType)

		// Unset reporting interval is valid.
		if err := validateReportingInterval(r, true); err != nil {
			t.Errorf("Rejected report with no reporting interval set: %v", err)
		}

		// All reporting interval values are valid.
		for _, reportingInterval := range reportingIntervalValues {
			r.ReportingInterval = reportingInterval
			if err := validateReportingInterval(r, true); err != nil {
				t.Errorf("Rejected report with valid %v reporting interval set: %v", reportingInterval, err)
			}
		}
	}

	// Check unsupported report types.
	for _, reportType := range unsupportedReportTypes {
		r := makeValidReportWithType(reportType)

		// Unset reporting interval is valid.
		if err := validateReportingInterval(r, true); err != nil {
			t.Errorf("Rejected report with no reporting interval set: %v", err)
		}

		// Only the unset reporting interval is allowed on non-supported report types.
		for _, reportingInterval := range reportingIntervalValues {
			r.ReportingInterval = reportingInterval
			if err := validateReportingInterval(r, true); err == nil {
				t.Errorf("No error returned for report type %v with reporting interval %v", r.ReportType, r.ReportingInterval)
			}
		}
	}
}

func TestValidateDisabledReportingInterval(t *testing.T) {
	allReportTypes := []config.ReportDefinition_ReportType{
		config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS,
		config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS,
		config.ReportDefinition_FLEETWIDE_HISTOGRAMS,
		config.ReportDefinition_FLEETWIDE_MEANS,
		config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS,
		config.ReportDefinition_STRING_COUNTS,
		config.ReportDefinition_UNIQUE_DEVICE_COUNTS,
		config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS,
		config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS,
		config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS,
	}

	reportingIntervalValues := []config.ReportDefinition_ReportingInterval{
		config.ReportDefinition_HOURS_1,
		config.ReportDefinition_DAYS_1,
	}

	for _, reportType := range allReportTypes {
		r := makeValidReportWithType(reportType)

		// Unset reporting interval is valid.
		if err := validateReportingInterval(r, false); err != nil {
			t.Errorf("Rejected report with no reporting interval set: %v", err)
		}

		// Verify an error is returned when setting reporting interval when the feature is disabled.
		for _, reportingInterval := range reportingIntervalValues {
			r.ReportingInterval = reportingInterval
			if err := validateReportingInterval(r, false); err == nil {
				t.Errorf("No error returned for report type %v with reporting interval %v", r.ReportType, r.ReportingInterval)
			}
		}
	}
}

// Test that deleted report IDs are not reused.
func TestDeletedReportIds(t *testing.T) {
	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	r := makeValidReportWithType(config.ReportDefinition_UNIQUE_DEVICE_COUNTS)
	r.LocalAggregationPeriod = config.WindowSize_WINDOW_1_DAY
	r.LocalAggregationProcedure = config.ReportDefinition_AT_LEAST_ONCE
	r.PrivacyLevel = config.ReportDefinition_NO_ADDED_PRIVACY
	m.DeletedReportIds = append(m.DeletedReportIds, r.Id+10)

	// Test that using a new report ID returns no error.
	if err := validateReportDefinitionForMetric(m, r); err != nil {
		t.Errorf("Rejected report with new report ID: %v", err)
	}

	// Test that reusing a previously deleted report ID returns an error.
	m.DeletedReportIds = append(m.DeletedReportIds, r.Id)
	if err := validateReportDefinitionForMetric(m, r); err == nil {
		t.Errorf("Accepted invalid report with reused deleted report ID")
	}
}

func TestValidatePrivacyMechanismAndConfig(t *testing.T) {
	// Default valid metric uses DEBUG max_release_stage.
	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	r := makeValidReportWithType(config.ReportDefinition_UNIQUE_DEVICE_COUNTS)
	if err := validatePrivacyMechanismAndConfig(m, r); err != nil {
		t.Errorf("Rejected report with no privacy mechanism: %v", err)
	}

	r.PrivacyMechanism = config.ReportDefinition_DE_IDENTIFICATION
	if err := validatePrivacyMechanismAndConfig(m, r); err != nil {
		t.Errorf("Rejected report with privacy mechanism DE_IDENTIFICATION: %v", err)
	}

	r.PrivacyMechanism = config.ReportDefinition_SHUFFLED_DIFFERENTIAL_PRIVACY
	if err := validatePrivacyMechanismAndConfig(m, r); err == nil {
		t.Errorf("Didn't rejected report with privacy mechanism SHUFFLED_DIFFERENTIAL_PRIVACY and empty config: %v", err)
	}

	r.PrivacyConfig = &config.ReportDefinition_ShuffledDp{
		ShuffledDp: &config.ReportDefinition_ShuffledDifferentialPrivacyConfig{
			Epsilon:            1,
			Delta:              0.001,
			ReportingThreshold: 10000,
			PoissonMean:        1,
		},
	}
	if err := validatePrivacyMechanismAndConfig(m, r); err != nil {
		t.Errorf("Rejected report with privacy mechanism SHUFFLED_DIFFERENTIAL_PRIVACY and not empty config: %v", err)
	}
}

func TestValidateShuffledDpReportPrivacy(t *testing.T) {
	m := makeValidMetric(config.MetricDefinition_OCCURRENCE)
	r := makeValidReportWithType(config.ReportDefinition_UNIQUE_DEVICE_COUNTS)

	r.LocalAggregationProcedure = config.ReportDefinition_AT_LEAST_ONCE
	r.PrivacyMechanism = config.ReportDefinition_SHUFFLED_DIFFERENTIAL_PRIVACY
	r.PrivacyConfig = &config.ReportDefinition_ShuffledDp{
		ShuffledDp: &config.ReportDefinition_ShuffledDifferentialPrivacyConfig{
			Epsilon:            1,
			Delta:              1e-10,
			ReportingThreshold: 1000,
			PoissonMean:        0.085937,
		},
	}

	if err := validateReportPoissonMean(m, r); err != nil {
		t.Errorf("Rejected report with valid privacy parameters with: %v", err)
	}

	r.PrivacyConfig.(*config.ReportDefinition_ShuffledDp).ShuffledDp.PoissonMean = 0.07
	if err := validateReportPoissonMean(m, r); err == nil {
		t.Error("Accepted report with invalid privacy parameters")
	}
}

func TestValidateShuffledDpConfigWithValidConfig(t *testing.T) {
	c := &config.ReportDefinition_ShuffledDifferentialPrivacyConfig{
		Epsilon:            1,
		Delta:              0.001,
		ReportingThreshold: 10000,
		PoissonMean:        1.0,
	}

	if err := validateShuffledDpConfig(c); err != nil {
		t.Errorf("Rejected valid config: %v", err)
	}
}

func TestValidateShuffledDpConfigWithInvalidEpsilon(t *testing.T) {
	invalidEpsilons := [2]float64{-1, 0}
	for _, e := range invalidEpsilons {
		c := &config.ReportDefinition_ShuffledDifferentialPrivacyConfig{
			Epsilon:            e,
			Delta:              0.001,
			ReportingThreshold: 10000,
			PoissonMean:        1,
		}
		if err := validateShuffledDpConfig(c); err == nil {
			t.Errorf("Didn't reject config with invalid Epsilon: %f", e)
		}
	}
}

func TestValidateShuffledDpConfigWithInvalidDelta(t *testing.T) {
	invalidDeltas := [4]float64{0, 1, 125, -1}
	for _, d := range invalidDeltas {
		c := &config.ReportDefinition_ShuffledDifferentialPrivacyConfig{
			Epsilon:            1,
			Delta:              d,
			ReportingThreshold: 10000,
		}
		if err := validateShuffledDpConfig(c); err == nil {
			t.Errorf("Didn't reject config with invalid Delta: %f", d)
		}
	}
}

func TestValidateShuffledDpConfigWithInvalidReportingThreshold(t *testing.T) {
	c := &config.ReportDefinition_ShuffledDifferentialPrivacyConfig{
		Epsilon:            1,
		Delta:              0.001,
		ReportingThreshold: 0,
	}
	if err := validateShuffledDpConfig(c); err == nil {
		t.Errorf("Didn't reject config with invalid ReportingThreshold: 0")
	}
}

func TestValidateShuffledDpConfigWithInvalidPoissonMean(t *testing.T) {
	invalidMeans := [4]float64{0, -1.0}
	for _, pm := range invalidMeans {
		c := &config.ReportDefinition_ShuffledDifferentialPrivacyConfig{
			Epsilon:            1,
			Delta:              0.01,
			ReportingThreshold: 10000,
			PoissonMean:        pm,
		}
		if err := validateShuffledDpConfig(c); err == nil {
			t.Errorf("Didn't reject config with invalid PoissonMean: %f", pm)
		}
	}
}

func TestValidateNewPrivacyFieldAndLegacyPrivacyFieldMatch(t *testing.T) {
	// Default valid metric uses DEBUG max_release_stage.
	r := makeValidReportWithType(config.ReportDefinition_UNIQUE_DEVICE_COUNTS)

	if err := validateNewPrivacyFieldAndLegacyPrivacyFieldMatch(r); err != nil {
		t.Errorf("Rejected report with matched privacy_level NO_ADDED_PRIVACY and privacy_mechanism DE_IDENTIFICATION: %v", err)
	}

	r.PrivacyLevel = config.ReportDefinition_LOW_PRIVACY
	if err := validateNewPrivacyFieldAndLegacyPrivacyFieldMatch(r); err == nil {
		t.Errorf("Didn't reject report with unmatched privacy_level LOW_PRIVACY and privacy_mechanism DE_IDENTIFICATION: %v", err)
	}

	r.PrivacyLevel = config.ReportDefinition_MEDIUM_PRIVACY
	if err := validateNewPrivacyFieldAndLegacyPrivacyFieldMatch(r); err == nil {
		t.Errorf("Didn't reject report with unmatched privacy_level MEDIUM_PRIVACY and privacy_mechanism DE_IDENTIFICATION: %v", err)
	}

	r.PrivacyLevel = config.ReportDefinition_HIGH_PRIVACY
	if err := validateNewPrivacyFieldAndLegacyPrivacyFieldMatch(r); err == nil {
		t.Errorf("Didn't reject report with unmatched privacy_level HIGH_PRIVACY and privacy_mechanism DE_IDENTIFICATION: %v", err)
	}

	r.PrivacyMechanism = config.ReportDefinition_SHUFFLED_DIFFERENTIAL_PRIVACY
	r.PrivacyLevel = config.ReportDefinition_NO_ADDED_PRIVACY
	if err := validateNewPrivacyFieldAndLegacyPrivacyFieldMatch(r); err == nil {
		t.Errorf("Didn't reject report with unmatched privacy_level NO_ADDED_PRIVACY and privacy_mechanism SHUFFLED_DIFFERENTIAL_PRIVACY: %v", err)
	}

	r.PoissonMean = 1
	r.ReportingThreshold = 10000
	r.PrivacyConfig = &config.ReportDefinition_ShuffledDp{
		ShuffledDp: &config.ReportDefinition_ShuffledDifferentialPrivacyConfig{
			Epsilon:            1,
			Delta:              0.001,
			ReportingThreshold: 10000,
			PoissonMean:        1,
		},
	}

	r.PrivacyLevel = config.ReportDefinition_LOW_PRIVACY
	if err := validateNewPrivacyFieldAndLegacyPrivacyFieldMatch(r); err != nil {
		t.Errorf("Rejected report with matched privacy_level LOW_PRIVACY and privacy_mechanism SHUFFLED_DIFFERENTIAL_PRIVACY: %v", err)
	}

	r.PrivacyLevel = config.ReportDefinition_MEDIUM_PRIVACY
	if err := validateNewPrivacyFieldAndLegacyPrivacyFieldMatch(r); err != nil {
		t.Errorf("Rejected report with matched privacy_level MEDIUM_PRIVACY and privacy_mechanism SHUFFLED_DIFFERENTIAL_PRIVACY: %v", err)
	}

	r.PrivacyLevel = config.ReportDefinition_HIGH_PRIVACY
	if err := validateNewPrivacyFieldAndLegacyPrivacyFieldMatch(r); err != nil {
		t.Errorf("Rejected report with matched privacy_level HIGH_PRIVACY and privacy_mechanism SHUFFLED_DIFFERENTIAL_PRIVACY: %v", err)
	}

	r.PoissonMean = 0.1
	if err := validateNewPrivacyFieldAndLegacyPrivacyFieldMatch(r); err == nil {
		t.Errorf("Didn't Rejected report with unmatched poisson_mean and shuffled_dp possion_mean: %v", err)
	}

	r.PoissonMean = 1
	r.ReportingThreshold = 1
	if err := validateNewPrivacyFieldAndLegacyPrivacyFieldMatch(r); err == nil {
		t.Errorf("Didn't Rejected report with unmatched reporting_threshold and shuffled_dp reporting_threshold: %v", err)
	}

}
