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

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

// Maps MetricTypes to valid ReportTypes.
var allowedReportTypes = map[config.MetricDefinition_MetricType]map[config.ReportDefinition_ReportType]bool{
	config.MetricDefinition_EVENT_OCCURRED: map[config.ReportDefinition_ReportType]bool{
		config.ReportDefinition_SIMPLE_OCCURRENCE_COUNT: true,
		config.ReportDefinition_UNIQUE_N_DAY_ACTIVES:    true,
	},
	config.MetricDefinition_EVENT_COUNT: map[config.ReportDefinition_ReportType]bool{
		config.ReportDefinition_EVENT_COMPONENT_OCCURRENCE_COUNT: true,
		config.ReportDefinition_INT_RANGE_HISTOGRAM:              true,
		config.ReportDefinition_NUMERIC_AGGREGATION:              true,
		config.ReportDefinition_PER_DEVICE_NUMERIC_STATS:         true,
		config.ReportDefinition_PER_DEVICE_HISTOGRAM:             true,
	},
	config.MetricDefinition_ELAPSED_TIME: map[config.ReportDefinition_ReportType]bool{
		config.ReportDefinition_INT_RANGE_HISTOGRAM:      true,
		config.ReportDefinition_NUMERIC_AGGREGATION:      true,
		config.ReportDefinition_PER_DEVICE_NUMERIC_STATS: true,
		config.ReportDefinition_PER_DEVICE_HISTOGRAM:     true,
	},
	config.MetricDefinition_FRAME_RATE: map[config.ReportDefinition_ReportType]bool{
		config.ReportDefinition_INT_RANGE_HISTOGRAM:      true,
		config.ReportDefinition_NUMERIC_AGGREGATION:      true,
		config.ReportDefinition_PER_DEVICE_NUMERIC_STATS: true,
		config.ReportDefinition_PER_DEVICE_HISTOGRAM:     true,
	},
	config.MetricDefinition_MEMORY_USAGE: map[config.ReportDefinition_ReportType]bool{
		config.ReportDefinition_INT_RANGE_HISTOGRAM:      true,
		config.ReportDefinition_NUMERIC_AGGREGATION:      true,
		config.ReportDefinition_PER_DEVICE_NUMERIC_STATS: true,
		config.ReportDefinition_PER_DEVICE_HISTOGRAM:     true,
	},
	config.MetricDefinition_INT_HISTOGRAM: map[config.ReportDefinition_ReportType]bool{
		config.ReportDefinition_INT_RANGE_HISTOGRAM: true,
	},
	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.MetricDefinition_CUSTOM: map[config.ReportDefinition_ReportType]bool{
		config.ReportDefinition_CUSTOM_RAW_DUMP: true,
	},
}

func reportTypeDeprecatedInCobalt11(r config.ReportDefinition_ReportType) bool {
	switch r {
	case config.ReportDefinition_SIMPLE_OCCURRENCE_COUNT,
		config.ReportDefinition_EVENT_COMPONENT_OCCURRENCE_COUNT,
		config.ReportDefinition_NUMERIC_AGGREGATION,
		config.ReportDefinition_INT_RANGE_HISTOGRAM,
		config.ReportDefinition_UNIQUE_N_DAY_ACTIVES,
		config.ReportDefinition_PER_DEVICE_NUMERIC_STATS,
		config.ReportDefinition_PER_DEVICE_HISTOGRAM:
		return true
	default:
		return false
	}
}

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
		}
	}

	return reportErrors.err()
}

// Validate a single instance of a ReportDefinition with its associated metric.
func validateReportDefinitionForMetric(m config.MetricDefinition, r config.ReportDefinition) error {
	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 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
	}

	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 {
	if reportTypeDeprecatedInCobalt11(r.ReportType) {
		return validateReportsDeprecatedInCobalt11(r)
	}

	// Report types maintained from Cobalt 1.0.
	switch r.ReportType {
	case config.ReportDefinition_CUSTOM_RAW_DUMP:
		return validateReportsMaintainedInCobalt11(r)
	}

	// All remaining report types are newly added in Cobalt 1.1.
	return validateReportsAddedInCobalt11(m, r)
}

// Validate reports with a type added in Cobalt 1.1.
func validateReportsAddedInCobalt11(m config.MetricDefinition, r config.ReportDefinition) error {
	if err := validateHasNoFieldsDeprecatedInCobalt11(r); err != nil {
		return err
	}

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

	if r.PrivacyLevel != config.ReportDefinition_NO_ADDED_PRIVACY {
		if err := validateReportWithPrivacy(r); err != nil {
			return err
		}
	}

	if err := validateLocalAggregationPeriod(r); err != nil {
		return err
	}

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

	switch r.ReportType {

	case config.ReportDefinition_STRING_COUNTS:
		return validateStringCountsReportDef(r)
	}

	return nil
}

// Validate reports with a type maintained from Cobalt 1.0.
func validateReportsMaintainedInCobalt11(r config.ReportDefinition) error {
	if err := validateHasNoFieldsDeprecatedInCobalt11(r); err != nil {
		return err
	}

	if r.PrivacyLevel != config.ReportDefinition_PRIVACY_LEVEL_UNKNOWN {
		return fmt.Errorf("The privacy_level field cannot be set for reports of type %s", r.ReportType)
	}

	return nil
}

// Validate reports with a type deprecated in Cobalt 1.1.
func validateReportsDeprecatedInCobalt11(r config.ReportDefinition) error {
	if err := validateHasNoCobalt11OnlyFields(r); err != nil {
		return err
	}

	switch r.ReportType {
	case config.ReportDefinition_SIMPLE_OCCURRENCE_COUNT:
		return validateSimpleOccurrenceCountReportDef(r)
	case config.ReportDefinition_UNIQUE_N_DAY_ACTIVES:
		return validateUniqueActivesReportDef(r)
	case config.ReportDefinition_PER_DEVICE_NUMERIC_STATS:
		return validatePerDeviceNumericStatsReportDef(r)
	case config.ReportDefinition_PER_DEVICE_HISTOGRAM:
		return validatePerDeviceHistogramReportDef(r)
	case config.ReportDefinition_NUMERIC_AGGREGATION:
		return validateNumericAggregationReportDef(r)
	}

	return nil
}

func validateReportWithPrivacy(r config.ReportDefinition) error {
	switch r.ReportType {
	case
		config.ReportDefinition_UNIQUE_DEVICE_HISTOGRAMS,
		config.ReportDefinition_UNIQUE_DEVICE_NUMERIC_STATS,
		config.ReportDefinition_HOURLY_VALUE_HISTOGRAMS,
		config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS,
		config.ReportDefinition_FLEETWIDE_HISTOGRAMS:
		if err := validateMinValueMaxValue(r); err != nil {
			return err
		}
	case
		config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS,
		config.ReportDefinition_STRING_COUNTS:
		if err := validateMaxCount(r); err != nil {
			return err
		}
	case config.ReportDefinition_FLEETWIDE_MEANS:
		if err := validateMinValueMaxValue(r); err != nil {
			return err
		}
		if err := validateMaxCount(r); err != nil {
			return err
		}
	}
	return nil
}

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:
		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)
		}
	}
	return nil
}

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

func validateSimpleOccurrenceCountReportDef(r config.ReportDefinition) error {
	if err := validateLocalPrivacyNoiseLevel(r); err != nil {
		return err
	}

	return nil
}

func validateUniqueActivesReportDef(r config.ReportDefinition) error {
	if err := validateWindowSize(r); err != nil {
		return err
	}
	if err := validateLocalPrivacyNoiseLevel(r); err != nil {
		return err
	}

	return nil
}

func validatePerDeviceNumericStatsReportDef(r config.ReportDefinition) error {
	if err := validateWindowSize(r); err != nil {
		return err
	}

	return nil
}

func validatePerDeviceHistogramReportDef(r config.ReportDefinition) error {
	if r.IntBuckets == nil {
		return fmt.Errorf("No int_buckets specified for report of type %s.", r.ReportType)
	}

	if err := validateWindowSize(r); err != nil {
		return err
	}

	return nil
}

func validateNumericAggregationReportDef(r config.ReportDefinition) error {
	if err := validatePercentiles(r); err != nil {
		return err
	}

	return nil
}

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)
	}

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

// Check that the report definition has a nonempty window_size field, and that none of the window sizes
// are UNSET.
func validateWindowSize(r config.ReportDefinition) error {
	if len(r.WindowSize) == 0 {
		return fmt.Errorf("No window_size specified for report of type %s.", r.ReportType)
	}
	for _, ws := range r.WindowSize {
		if ws == config.WindowSize_UNSET {
			return fmt.Errorf("Unset window size found for report of type %s.", r.ReportType)
		}
	}

	return nil
}

// Check that the local_privacy_noise_level field is set.
func validateLocalPrivacyNoiseLevel(r config.ReportDefinition) error {
	if r.LocalPrivacyNoiseLevel == config.ReportDefinition_NOISE_LEVEL_UNSET {
		return fmt.Errorf("No local_privacy_noise_level specified for report of type %s.", r.ReportType)
	}

	return nil
}

// Check that the percentiles are between 0 and 100.
func validatePercentiles(r config.ReportDefinition) error {
	for _, percentage := range r.Percentiles {
		if percentage < 0 || percentage > 100 {
			return fmt.Errorf(
				"Percentiles must be in the range 0-100.  Received value %d for report of type %s.",
				percentage, r.ReportType)
		}
	}

	return nil
}

func validateMaxCount(r config.ReportDefinition) error {
	if r.MaxCount == 0 {
		return fmt.Errorf("max_count must be set for reports of type %s", r.ReportType)
	}

	return nil
}

func validateMinValueMaxValue(r config.ReportDefinition) error {
	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 smaller than max_value: %v >= %v", r.MinValue, r.MaxValue)
	}

	return nil
}

func validateHasNoCobalt11OnlyFields(r config.ReportDefinition) error {
	rt := r.ReportType
	if r.PrivacyLevel != config.ReportDefinition_PRIVACY_LEVEL_UNKNOWN {
		return fmt.Errorf("The privacy_level field cannot be set for reports of type %s", rt)
	}

	if r.MinValue != 0 || r.MaxValue != 0 || r.MaxCount != 0 {
		return fmt.Errorf("The min_value, max_value and max_count field cannot be set for reports of type %s", rt)
	}

	if r.LocalAggregationProcedure != config.ReportDefinition_LOCAL_AGGREGATION_PROCEDURE_UNSET {
		return fmt.Errorf("The local_aggregation_procedure field cannot be set for reports of type %s", rt)
	}

	if r.LocalAggregationProcedurePercentileN != 0 {
		return fmt.Errorf("The field local_aggregation_procedure_percentile_n cannot be set for reports of type %s", rt)
	}

	if r.LocalAggregationPeriod != config.WindowSize_UNSET {
		return fmt.Errorf("The local_aggregation_period field cannot be set for reports of type %s", rt)
	}

	return nil
}

func validateHasNoFieldsDeprecatedInCobalt11(r config.ReportDefinition) error {
	rt := r.ReportType
	if r.LocalPrivacyNoiseLevel != config.ReportDefinition_NOISE_LEVEL_UNSET {
		return fmt.Errorf("The local_privacy_noise_level field cannot be set for reports of type %s", rt)
	}

	if r.CandidateList != nil && len(r.CandidateList) != 0 {
		return fmt.Errorf("The candidate_list field cannot be set for reports of type %s", rt)
	}

	if len(r.WindowSize) != 0 {
		return fmt.Errorf("The window_size field cannot be set for reports of type %s", rt)
	}

	if len(r.AggregationWindow) != 0 {
		return fmt.Errorf("The aggregation_window field cannot be set for reports of type %s", rt)
	}

	return nil
}
