// 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"
	"flag"
	"fmt"
	"math"
	"privacy"
)

// This file contains logic to validate list of ReportDefinition protos in MetricDefinition protos.

var (
	noHourlyReports        = flag.Bool("no_hourly_reports", false, "Don't allow reports that send data hourly in the registry.")
	allowReportingInterval = flag.Bool("allow_reporting_interval", false, "Allow the `reporting_interval` to be set in reports.")
	validatePoissonMean    = flag.Bool("validate_poisson_mean", false, "Validate that the specified poisson_mean is sufficient to provide the specified privacy level.")
)

// errIllegalHourlyReport is returned in validations when no_hourly_reports is set and an hourly report is encountered.
var errIllegalHourlyReport = errors.New("hourly reports are not allowed")

// Maps MetricTypes to valid ReportTypes.
var allowedReportTypes = map[config.MetricDefinition_MetricType]map[config.ReportDefinition_ReportType]bool{
	config.MetricDefinition_OCCURRENCE: map[config.ReportDefinition_ReportType]bool{
		config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS: true,
		config.ReportDefinition_UNIQUE_DEVICE_COUNTS:        true,
		config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS:    true,
		config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS:     true,
		config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS: true,
		config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS:  true,
	},
	config.MetricDefinition_INTEGER: map[config.ReportDefinition_ReportType]bool{
		config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS:    true,
		config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS:     true,
		config.ReportDefinition_FLEETWIDE_HISTOGRAMS:        true,
		config.ReportDefinition_FLEETWIDE_MEANS:             true,
		config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS: true,
		config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS:  true,
	},
	config.MetricDefinition_INTEGER_HISTOGRAM: map[config.ReportDefinition_ReportType]bool{
		config.ReportDefinition_FLEETWIDE_HISTOGRAMS: true,
	},
	config.MetricDefinition_STRING: map[config.ReportDefinition_ReportType]bool{
		config.ReportDefinition_STRING_COUNTS:               true,
		config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS: true,
	},
}

// For reports that must specify a policy, this is the suggestion we will give.
var SuggestedSystemProfileSelectionPolicy = map[config.ReportDefinition_ReportType]config.SystemProfileSelectionPolicy{
	config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS:     config.SystemProfileSelectionPolicy_SELECT_LAST,
	config.ReportDefinition_UNIQUE_DEVICE_COUNTS:        config.SystemProfileSelectionPolicy_SELECT_LAST,
	config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS:    config.SystemProfileSelectionPolicy_SELECT_LAST,
	config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS: config.SystemProfileSelectionPolicy_SELECT_LAST,
}

// These report types must not set 'system_profile_selection' in the registry.
// The 'system_profile_selection' field must always be set to REPORT_ALL.
// See: //src/bin/config_parser/src/config_parser/expand_defaults.go
var ReportAllOnlyReports = map[config.ReportDefinition_ReportType]bool{
	config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS: true,
	config.ReportDefinition_FLEETWIDE_HISTOGRAMS:        true,
	config.ReportDefinition_FLEETWIDE_MEANS:             true,
	config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS: true,
	config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS:  true,
	config.ReportDefinition_STRING_COUNTS:               true,
}

func validateReportDefinitions(m *config.MetricDefinition) error {
	reportErrors := newValidationErrors("report")

	reportIds := map[uint32]int{}
	reportNames := map[string]bool{}
	for i, r := range m.Reports {
		if _, ok := reportIds[r.Id]; ok {
			reportErrors.addError(fmt.Sprintf("Report %d", r.Id), fmt.Errorf("there are two reports with id=%v", r.Id))
			continue
		}
		reportIds[r.Id] = i

		if _, ok := reportNames[r.ReportName]; ok {
			reportErrors.addError(r.ReportName, fmt.Errorf("there are two reports with name=%v", r.ReportName))
			continue
		}
		reportNames[r.ReportName] = true

		if err := validateReportDefinitionForMetric(m, r); err != nil {
			reportErrors.addError(r.ReportName, err)
			continue
		}

		if suggestion, ok := SuggestedSystemProfileSelectionPolicy[r.ReportType]; ok {
			if r.SystemProfileSelection == config.SystemProfileSelectionPolicy_SELECT_DEFAULT {
				reportErrors.addError(r.ReportName, fmt.Errorf("you must manually specify the system_profile_selection for this report (%v may be a good choice)", suggestion))
			}
		}

		if _, ok := ReportAllOnlyReports[r.ReportType]; ok {
			// N.B.: config_parser/expand_defaults.go is run before validation, so SELECT_DEFAULT will get expanded to REPORT_ALL for appropriate metrics.
			if r.SystemProfileSelection != config.SystemProfileSelectionPolicy_REPORT_ALL {
				reportErrors.addError(r.ReportName, fmt.Errorf("reports of type %v should not manually specify system_profile_selection. The default value is REPORT_ALL", r.ReportType))
			}
		}
	}

	return reportErrors.err()
}

// Validate a single instance of a ReportDefinition with its associated metric.
func validateReportDefinitionForMetric(m *config.MetricDefinition, r *config.ReportDefinition) error {
	for _, deletedReportId := range m.DeletedReportIds {
		if r.Id == deletedReportId {
			return fmt.Errorf("IDs from previously deleted reports are being reused, choose a new report ID for %v", r.Id)
		}
	}

	// If the customer is using Fuchsia, then there mustn't be an app_version in
	// the SystemProfileField. Currently the customers using Fuchsia are
	// fuchsia: 1, cobalt_internal: 2147483647 (MaxInt32) and turquoise: 100000.
	fuchsiaCustomerIds := []uint32{1, math.MaxInt32, 100000}
	for _, id := range fuchsiaCustomerIds {
		if m.CustomerId == id {
			if err := validateReportHasNoAppVersionField(r); err != nil {
				return err
			}
		}
	}

	if err := validateReportType(m.MetricType, r.ReportType); err != nil {
		return err
	}

	if err := validateIntBucketsForReport(m, r); err != nil {
		return err
	}

	if err := validateReportDefinition(m, r); err != nil {
		return err
	}

	return nil
}

// Validate that the system profile field does not have and app_version.
func validateReportHasNoAppVersionField(r *config.ReportDefinition) error {
	for _, spf := range r.GetSystemProfileField() {
		if spf == config.SystemProfileField_APP_VERSION {
			return fmt.Errorf("app_version must not be part of the" +
				"system_profile_field")
		}
	}
	return nil
}

// Validate a single instance of a ReportDefinition.
func validateReportDefinition(m *config.MetricDefinition, r *config.ReportDefinition) error {
	if !validNameRegexp.MatchString(r.ReportName) {
		return fmt.Errorf("Invalid report name. Report names must match the regular expression '%v'", validNameRegexp)
	}

	if r.Id == 0 {
		return fmt.Errorf("Report ID of zero is not allowed. Please specify a positive report ID.")
	}

	if err := validateReportDefinitionForType(m, r); err != nil {
		return err
	}

	if *noHourlyReports {
		if err := validateNoHourlyReports(m, r); err != nil {
			return err
		}
	}

	return nil
}

// Validates that the MetricType and ReportType provided are compatible.
func validateReportType(mt config.MetricDefinition_MetricType, rt config.ReportDefinition_ReportType) error {
	if rt == config.ReportDefinition_REPORT_TYPE_UNSET {
		return fmt.Errorf("report_type is not set")
	}

	rts, ok := allowedReportTypes[mt]
	if !ok {
		return fmt.Errorf("unknown metric type %s", mt)
	}

	if _, ok = rts[rt]; !ok {
		return fmt.Errorf("reports of type %s cannot be used with metrics of type %s", rt, mt)
	}

	return nil
}

// Validates ReportDefinitions of some types.
func validateReportDefinitionForType(m *config.MetricDefinition, r *config.ReportDefinition) error {
	return validateReports(m, r)
}

// Validate reports.
func validateReports(m *config.MetricDefinition, r *config.ReportDefinition) error {
	reportErrors := newValidationErrors("field")

	if r.PrivacyLevel == config.ReportDefinition_PRIVACY_LEVEL_UNKNOWN {
		reportErrors.addError("privacy_level", fmt.Errorf("The privacy_level field is required for reports of type %s", r.ReportType))
	}

	if r.PrivacyMechanism == config.ReportDefinition_PRIVACY_MECHANISM_UNSPECIFIED {
		reportErrors.addError("privacy_mechanism", fmt.Errorf("The privacy_mechanism field is required for reports of type %s", r.ReportType))
	}

	if err := validatePoissonFields(r); err != nil {
		reportErrors.addError("poisson_mean, num_index_points, or string_sketch_params", err)
	}

	if err := validateMinValueMaxValue(r); err != nil {
		reportErrors.addError("min_value or max_value", err)
	}

	if err := validateMaxCount(r); err != nil {
		reportErrors.addError("max_count", err)
	}

	if err := validateLocalAggregationPeriod(r); err != nil {
		reportErrors.addError("local_aggregation_period", err)
	}

	if err := validateLocalAggregationProcedure(m, r); err != nil {
		reportErrors.addError("local_aggregation_procedure", err)
	}

	if err := validateExpeditedSending(m, r); err != nil {
		reportErrors.addError("expedited_sending", err)
	}

	if err := validateMaxReleaseStage(m, r); err != nil {
		reportErrors.addError("max_release_stage", err)
	}

	if err := validateReportingInterval(r, *allowReportingInterval); err != nil {
		reportErrors.addError("reporting_interval", err)
	}

	if err := validateExemptFromConsent(r); err != nil {
		reportErrors.addError("exempt_from_consent", err)
	}

	if err := validateMaxPrivateIndex(m, r); err != nil {
		reportErrors.addError("metric_dimensions, int_buckets, or num_index_points", err)
	}

	switch r.ReportType {

	case config.ReportDefinition_STRING_COUNTS:
		if err := validateStringCountsReportDef(r); err != nil {
			reportErrors.addError("other", err)
		}
	case config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS:
		if err := validateUniqueDeviceStringCountsReportDef(r); err != nil {
			reportErrors.addError("other", err)
		}
	}

	if err := validatePrivacyMechanismAndConfig(m, r); err != nil {
		reportErrors.addError("other", err)
	}

	if err := validateNewPrivacyFieldAndLegacyPrivacyFieldMatch(r); err != nil {
		reportErrors.addError("other", err)
	}

	return reportErrors.err()
}

func validateLocalAggregationPeriod(r *config.ReportDefinition) error {
	switch r.ReportType {
	case config.ReportDefinition_UNIQUE_DEVICE_COUNTS,
		config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS,
		config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS,
		config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS:
		if r.LocalAggregationPeriod == config.WindowSize_UNSET {
			return fmt.Errorf("day based metrics must specify a local_aggregation_period")
		}
	case 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:
		if r.LocalAggregationPeriod != config.WindowSize_UNSET {
			return fmt.Errorf("hour based metrics must not specify a local_aggregation_period")
		}
	}
	return nil
}

func validateLocalAggregationProcedure(m *config.MetricDefinition, r *config.ReportDefinition) error {
	switch r.ReportType {
	case config.ReportDefinition_UNIQUE_DEVICE_COUNTS:
		switch r.LocalAggregationProcedure {
		case config.ReportDefinition_AT_LEAST_ONCE,
			config.ReportDefinition_SELECT_FIRST,
			config.ReportDefinition_SELECT_MOST_COMMON:
		default:
			return fmt.Errorf("reports of type UNIQUE_DEVICE_COUNTS must specify a local_aggregation_procedure in the list (AT_LEAST_ONCE, SELECT_FIRST, SELECT_MOST_COMMON)")
		}
	case config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS,
		config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS,
		config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS,
		config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS:
		if m.MetricType == config.MetricDefinition_INTEGER {
			if r.LocalAggregationProcedure == config.ReportDefinition_LOCAL_AGGREGATION_PROCEDURE_UNSET {
				return fmt.Errorf("INTEGER metrics with reports of type %v must specify a local_aggregation_procedure", r.ReportType)
			}
			switch r.LocalAggregationProcedure {
			case config.ReportDefinition_SUM_PROCEDURE,
				config.ReportDefinition_MIN_PROCEDURE,
				config.ReportDefinition_MAX_PROCEDURE,
				config.ReportDefinition_MEAN,
				config.ReportDefinition_MEDIAN,
				config.ReportDefinition_PERCENTILE_N:
			default:
				return fmt.Errorf("INTEGER metrics with reports of type %v do not support the local_aggregation_procedure %v. Must be one of (SUM_PROCEDURE, MIN_PROCEDURE, MAX_PROCEDURE, MEAN, MEDIAN, PERCENTILE_N)", r.ReportType, r.LocalAggregationProcedure)
			}

			if r.LocalAggregationProcedure == config.ReportDefinition_PERCENTILE_N {
				if r.LocalAggregationProcedurePercentileN == 0 || r.LocalAggregationProcedurePercentileN >= 100 {
					return fmt.Errorf("metrics with PERCENTILE_N local_aggregation_procedure must set local_aggregation_procedure_percentile_n in (0, 100)")
				}
			}
		} else if m.MetricType == config.MetricDefinition_OCCURRENCE {
			if r.LocalAggregationProcedure != config.ReportDefinition_LOCAL_AGGREGATION_PROCEDURE_UNSET {
				return fmt.Errorf("OCCURRENCE metrics with reports of type %v do not support local_aggregation_procedure", r.ReportType)
			}
		}
	default:
		if r.LocalAggregationProcedure != config.ReportDefinition_LOCAL_AGGREGATION_PROCEDURE_UNSET {
			return fmt.Errorf("reports of type %v do not support local_aggregation_procedure", r.ReportType)
		}
	}
	if r.LocalAggregationProcedure == config.ReportDefinition_SELECT_FIRST && r.EventVectorBufferMax > 1 {
		return fmt.Errorf("reports with local_aggregation_procedure: SELECT_FIRST should not set event_vector_buffer_max to a value other than 1 (the default)")
	}

	return nil
}

func validateExpeditedSending(m *config.MetricDefinition, r *config.ReportDefinition) error {
	if !r.ExpeditedSending {
		return nil
	}
	switch r.ReportType {
	case config.ReportDefinition_UNIQUE_DEVICE_COUNTS:
		switch r.LocalAggregationProcedure {
		case config.ReportDefinition_AT_LEAST_ONCE,
			config.ReportDefinition_SELECT_FIRST:
		default:
			return fmt.Errorf("reports of type UNIQUE_DEVICE_COUNTS with expedited_sending enabled must specify a local_aggregation_procedure in the list (AT_LEAST_ONCE, SELECT_FIRST)")
		}
	case config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS:
	default:
		return fmt.Errorf("reports of type %v do not support expedited_sending", r.ReportType)
	}
	if r.PrivacyLevel != config.ReportDefinition_NO_ADDED_PRIVACY {
		return fmt.Errorf("The expedited_sending can not be enabled unless the privacy_level field is set to NO_ADDED_PRIVACY")
	}
	return nil
}

func validateMaxReleaseStage(m *config.MetricDefinition, r *config.ReportDefinition) error {
	if r.MaxReleaseStage == config.ReleaseStage_RELEASE_STAGE_NOT_SET {
		return nil
	}
	if r.MaxReleaseStage > m.MetaData.MaxReleaseStage {
		return fmt.Errorf("report is collected in report stage %v which is later than its metric which has a report stage of %v", r.MaxReleaseStage, m.MetaData.MaxReleaseStage)
	}
	return nil
}

// Validates there are no hourly reports.
func validateNoHourlyReports(m *config.MetricDefinition, r *config.ReportDefinition) error {
	// Currently the hourly reports are identified by the report type only.
	switch r.ReportType {
	case config.ReportDefinition_UNIQUE_DEVICE_COUNTS,
		config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS,
		config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS,
		config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS:
		return nil
	case config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS,
		config.ReportDefinition_STRING_COUNTS:
		if r.ReportingInterval == config.ReportDefinition_DAYS_1 {
			return nil
		}
		fallthrough
	case config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS,
		config.ReportDefinition_FLEETWIDE_HISTOGRAMS,
		config.ReportDefinition_FLEETWIDE_MEANS,
		config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS:
		return errIllegalHourlyReport
	}
	return fmt.Errorf("report of type %v is not expected", r.ReportType)
}

// Validates the `reporting_interval` field.
func validateReportingInterval(r *config.ReportDefinition, allowed bool) error {
	// Currently only FLEETWIDE_OCCURRENCE_COUNTS reports potentially support
	// setting the `reporting_interval` flag.
	switch r.ReportingInterval {
	case config.ReportDefinition_REPORTING_INTERVAL_UNSET:
		return nil
	default:
		if allowed && (r.ReportType == config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS || r.ReportType == config.ReportDefinition_STRING_COUNTS) {
			return nil
		}
		return fmt.Errorf("setting `reporting_interval` is not allowed for type %v", r.ReportType)
	}
}

// Validates the `exempt_from_consent` field.
func validateExemptFromConsent(r *config.ReportDefinition) error {
	if !r.ExemptFromConsent {
		return nil
	}
	if r.PrivacyLevel == config.ReportDefinition_NO_ADDED_PRIVACY {
		return fmt.Errorf("setting `exempt_from_consent` is not allowed unless differential privacy is enabled")
	}

	return nil
}

// Validates that the max private index value fits in a signed int32.
func validateMaxPrivateIndex(m *config.MetricDefinition, r *config.ReportDefinition) error {
	if r.PrivacyLevel == config.ReportDefinition_NO_ADDED_PRIVACY {
		return nil
	}
	numPrivateIndices, err := privacy.GetNumPrivateIndices(m, r)
	if err != nil {
		return err
	}
	if numPrivateIndices >= math.MaxInt32 {
		return fmt.Errorf("privacy enabled reports can not handle more than a signed int32 of possible values, try reducing the number of dimensions/events, histogram buckets, or num_index_points, current number of indices is: %v", numPrivateIndices)
	}
	return nil
}

/////////////////////////////////////////////////////////////////
// Validation for specific report types:
/////////////////////////////////////////////////////////////////

func validateStringCountsReportDef(r *config.ReportDefinition) error {
	if r.IntBuckets != nil {
		return fmt.Errorf("int_buckets can not be specified for report of type %s.", r.ReportType)
	}
	if r.StringBufferMax == 0 {
		return fmt.Errorf("no string_buffer_max specified for report of type %s.", r.ReportType)
	}

	return nil
}

func validateUniqueDeviceStringCountsReportDef(r *config.ReportDefinition) error {
	if r.IntBuckets != nil {
		return fmt.Errorf("int_buckets can not be specified for report of type %s.", r.ReportType)
	}
	if r.StringBufferMax == 0 {
		return fmt.Errorf("no string_buffer_max specified for report of type %s.", r.ReportType)
	}

	return nil
}

/////////////////////////////////////////////////////////////////
// Validation for specific fields of report definitions
//
// These functions are oblivious to the report's type and should
// only be called with reports for which that field is required.
/////////////////////////////////////////////////////////////////

func validatePoissonFields(r *config.ReportDefinition) error {
	if r.PrivacyLevel != config.ReportDefinition_NO_ADDED_PRIVACY {
		if r.PoissonMean == 0.0 {
			return fmt.Errorf("poisson_mean must be set when privacy_level is not NO_ADDED_PRIVACY")
		}
		if r.PoissonMean < 0.0 {
			return fmt.Errorf("poisson_mean should not be negative")
		}
		if r.NumIndexPoints == 0 {
			return fmt.Errorf("num_index_points must be set when privacy_level is not NO_ADDED_PRIVACY")
		}
		if r.ReportType == config.ReportDefinition_STRING_COUNTS || r.ReportType == config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS {
			if r.GetStringSketchParams() == nil {
				return fmt.Errorf("string_sketch_params must be set for string reports when privacy_level is not NO_ADDED_PRIVACY")
			}
		}
	} else {
		if r.PoissonMean != 0.0 {
			return fmt.Errorf("poisson_mean should not be set when privacy_level is not NO_ADDED_PRIVACY")
		}
	}

	return nil
}

func validateMinValueMaxValue(r *config.ReportDefinition) error {
	switch r.PrivacyLevel {
	case
		config.ReportDefinition_PRIVACY_LEVEL_UNKNOWN:
		return nil
	case
		config.ReportDefinition_NO_ADDED_PRIVACY:
		if r.MaxValue != 0 || r.MinValue != 0 {
			return fmt.Errorf("min_value and max_value should not be set for reports with no added privacy")
		}
	case
		config.ReportDefinition_LOW_PRIVACY,
		config.ReportDefinition_MEDIUM_PRIVACY,
		config.ReportDefinition_HIGH_PRIVACY:
		switch r.ReportType {
		case
			config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS,
			config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS,
			config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS,
			config.ReportDefinition_FLEETWIDE_MEANS:
			if r.MaxValue == 0 && r.MinValue == 0 {
				return fmt.Errorf("min_value and max_value must be set for reports of type %s", r.ReportType)
			}

			if r.MaxValue < r.MinValue {
				return fmt.Errorf("min_value must be less than or equal to max_value: %v > %v", r.MinValue, r.MaxValue)
			}
		case
			config.ReportDefinition_UNIQUE_DEVICE_COUNTS,
			config.ReportDefinition_FLEETWIDE_HISTOGRAMS,
			config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS,
			config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS,
			config.ReportDefinition_STRING_COUNTS,
			config.ReportDefinition_UNIQUE_DEVICE_STRING_COUNTS:
			if r.MinValue != 0 || r.MaxValue != 0 {
				return fmt.Errorf("min_value and max_value should not be set for reports of type %s", r.ReportType)
			}
		default:
			return fmt.Errorf("unrecognized report type %s", r.ReportType)
		}
	}
	return nil
}

func validateMaxCount(r *config.ReportDefinition) error {
	switch r.PrivacyLevel {
	case
		config.ReportDefinition_PRIVACY_LEVEL_UNKNOWN:
		return nil
	case
		config.ReportDefinition_NO_ADDED_PRIVACY:
		if r.MaxCount != 0 {
			return fmt.Errorf("max_count should not be set for reports with no added privacy")
		}
	case
		config.ReportDefinition_LOW_PRIVACY,
		config.ReportDefinition_MEDIUM_PRIVACY,
		config.ReportDefinition_HIGH_PRIVACY:
		switch r.ReportType {
		case
			config.ReportDefinition_FLEETWIDE_HISTOGRAMS,
			config.ReportDefinition_STRING_COUNTS,
			config.ReportDefinition_FLEETWIDE_MEANS:
			if r.MaxCount == 0 {
				return fmt.Errorf("max_count must be set for reports of type %s", r.ReportType)
			}
		case
			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:
			if r.MaxCount != 0 {
				return fmt.Errorf("max_count should not be set for reports of type %s", r.ReportType)
			}

		default:
			return fmt.Errorf("unrecognized report type %s", r.ReportType)
		}
	}
	return nil
}

// Validates that new privacy field values matches the legacy private field values. This validation assumes legacy and new privacy fields are already validated.
func validateNewPrivacyFieldAndLegacyPrivacyFieldMatch(r *config.ReportDefinition) error {
	switch r.PrivacyLevel {
	case config.ReportDefinition_NO_ADDED_PRIVACY:
		if r.PrivacyMechanism != config.ReportDefinition_DE_IDENTIFICATION {
			return fmt.Errorf("privacy_mechanism should set to DE_IDENTIFICATION when privacy_level is NO_ADDED_PRIVACY")
		}
	case config.ReportDefinition_LOW_PRIVACY,
		config.ReportDefinition_MEDIUM_PRIVACY,
		config.ReportDefinition_HIGH_PRIVACY:
		if r.PrivacyMechanism != config.ReportDefinition_SHUFFLED_DIFFERENTIAL_PRIVACY {
			return fmt.Errorf("privacy_mechanism should set to SHUFFLED_DIFFERENTIAL_PRIVACY when privacy_level is not NO_ADDED_PRIVACY")
		}
		switch op := r.PrivacyConfig.(type) {
		case *config.ReportDefinition_ShuffledDp:
			if op.ShuffledDp.PoissonMean != r.PoissonMean {
				return fmt.Errorf("the value of poission_mean in shuffled_dp should match the value of poission_mean")
			}
			if op.ShuffledDp.ReportingThreshold != r.ReportingThreshold {
				return fmt.Errorf("the value of reporting_threshold in shuffled_dp should match the value of reporting_threshold")
			}
		default:
			return fmt.Errorf("Unhandled privacy config")
		}
	}

	return nil
}

func validatePrivacyMechanismAndConfig(m *config.MetricDefinition, r *config.ReportDefinition) error {
	switch r.PrivacyMechanism {
	case config.ReportDefinition_DE_IDENTIFICATION:
		if r.PrivacyConfig != nil {
			return fmt.Errorf("you shouldn't specify privacy config when select DE_IDENTIFICATION")
		}
	case config.ReportDefinition_SHUFFLED_DIFFERENTIAL_PRIVACY:
		if r.PrivacyConfig != nil {
			switch op := r.PrivacyConfig.(type) {
			case *config.ReportDefinition_ShuffledDp:
				if err := validateShuffledDpConfig(op.ShuffledDp); err != nil {
					return err
				}

				if *validatePoissonMean {
					return validateReportPoissonMean(m, r)
				}

				return nil
			default:
				return fmt.Errorf("you specified the wrong privacy config, you should specify shuffled_dp privacy config when select SHUFFLED_DIFFERENTIAL_PRIVACY")
			}
		}
		return fmt.Errorf("you should specify shuffled_dp privacy config  when select SHUFFLED_DIFFERENTIAL_PRIVACY")
	}

	return nil
}

func validateReportPoissonMean(m *config.MetricDefinition, r *config.ReportDefinition) error {
	p, err := privacy.GetPrivacyParamsForReport(m, r)
	if err != nil {
		return err
	}

	if err := p.Validate(); err != nil {
		return err
	}

	return nil
}

func validateShuffledDpConfig(c *config.ReportDefinition_ShuffledDifferentialPrivacyConfig) error {
	if c.Epsilon <= 0 {
		return fmt.Errorf("epsilon is %f, must be > 0", c.Epsilon)
	}

	if c.Delta <= 0 || c.Delta >= 1 {
		return fmt.Errorf("delta %e must be > 0 and < 1", c.Delta)
	}

	if c.ReportingThreshold <= 0 {
		return fmt.Errorf("reporting threshold must be > 0")
	}

	if c.PoissonMean <= 0.0 {
		return fmt.Errorf("poisson_mean must be set and should not be negative")
	}

	return nil
}
