// 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"
	"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 makeValidReportWithName("the_report_name")
}

func makeValidReportWithName(name string) config.ReportDefinition {
	return config.ReportDefinition{
		Id:         10,
		ReportName: name,
		ReportType: config.ReportDefinition_EVENT_COMPONENT_OCCURRENCE_COUNT,
	}
}

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

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

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

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

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

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

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

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

// Test that validateLocalPrivacyNoiseLevel accepts a ReportDefinition if and only if it has a local_privacy_noise_level field.
func TestValidateLocalPrivacyNoiseLevel(t *testing.T) {
	r := makeValidReport()

	if err := validateLocalPrivacyNoiseLevel(r); err == nil {
		t.Error("Accepted report definition with local_privacy_noise_level unset.")
	}

	r.LocalPrivacyNoiseLevel = config.ReportDefinition_SMALL
	if err := validateLocalPrivacyNoiseLevel(r); err != nil {
		t.Errorf("Rejected report definition with local_privacy_noise_level set: %v", err)
	}
}

// Test that validateWindowSize rejects a ReportDefinition with no window_size field, and a ReportDefinition with a
// window_size field where one of the window sizes is UNSET.
func TestValidateWindowSize(t *testing.T) {
	r := makeValidReport()

	if err := validateWindowSize(r); err == nil {
		t.Error("Accepted report definition without window_size field.")
	}

	r.WindowSize = []config.WindowSize{config.WindowSize_WINDOW_1_DAY, config.WindowSize_UNSET}
	if err := validateWindowSize(r); err == nil {
		t.Error("Accepted report definition with an UNSET window size.")
	}

	r.WindowSize = []config.WindowSize{config.WindowSize_WINDOW_1_DAY, config.WindowSize_WINDOW_7_DAYS}
	if err := validateWindowSize(r); err != nil {
		t.Errorf("Rejected report definition with valid window_size field: %v", err)
	}
}

// Test that local_privacy_noise_level must be set if the report type is SIMPLE_OCCURRENCE_COUNT.
func TestValidateReportDefinitionForSimpleOccurrenceCount(t *testing.T) {
	r := makeValidReport()
	r.ReportType = config.ReportDefinition_SIMPLE_OCCURRENCE_COUNT

	if err := validateReportDefinition(r); err == nil {
		t.Error("Accepted report definition of type SIMPLE_OCCURRENCE_COUNT with local_privacy_noise_level unset.")
	}
}

// Test that local_privacy_noise_level and window_size must be set if the report type is UNIQUE_N_DAY_ACTIVES.
func TestValidateReportDefinitionForUniqueActives(t *testing.T) {
	r := makeValidReport()
	r.ReportType = config.ReportDefinition_UNIQUE_N_DAY_ACTIVES

	// Add a valid window_size, but not a local_privacy_noise_level.
	r.WindowSize = []config.WindowSize{config.WindowSize_WINDOW_1_DAY}
	if err := validateReportDefinition(r); err == nil {
		t.Error("Accepted report definition of type UNIQUE_N_DAY_ACTIVES with local_privacy_noise_level unset.")
	}

	// Remove window_size and add a local_privacy_noise_level.
	r.WindowSize = []config.WindowSize{}
	r.LocalPrivacyNoiseLevel = config.ReportDefinition_SMALL
	if err := validateReportDefinition(r); err == nil {
		t.Error("Accepted report definition of type UNIQUE_N_DAY_ACTIVES without window_size field.")
	}

	// Add a valid window size to window_size, but also add an UNSET window size.
	r.WindowSize = []config.WindowSize{config.WindowSize_WINDOW_1_DAY, config.WindowSize_UNSET}
	if err := validateReportDefinition(r); err == nil {
		t.Error("Accepted report definition of type UNIQUE_N_DAY_ACTIVES with window_size field containing an UNSET window size.")
	}
}

// Test that window_size must be set if the report type is PER_DEVICE_NUMERIC_STATS.
func TestValidateReportDefinitionForPerDeviceNumericStats(t *testing.T) {
	r := makeValidReport()
	r.ReportType = config.ReportDefinition_PER_DEVICE_NUMERIC_STATS

	if err := validateReportDefinition(r); err == nil {
		t.Error("Accepted report definition of type PER_DEVICE_NUMERIC_STATS without window_size field.")
	}

	// Add a valid window size to window_size, but also add an UNSET window size.
	r.WindowSize = []config.WindowSize{config.WindowSize_WINDOW_1_DAY, config.WindowSize_UNSET}
	if err := validateReportDefinition(r); err == nil {
		t.Error("Accepted report definition of type PER_DEVICE_NUMERIC_STATS with window_size field containing an UNSET window size.")
	}
}

// Test that window_size must be set if the report type is PER_DEVICE_HISTOGRAM.
func TestValidateReportDefinitionForPerDeviceHistogram(t *testing.T) {
	r := makeValidReport()
	r.ReportType = config.ReportDefinition_PER_DEVICE_HISTOGRAM

	if err := validateReportDefinition(r); err == nil {
		t.Error("No int_buckets specified for report of type PER_DEVICE_HISTOGRAM.")
	}

	r.IntBuckets = &config.IntegerBuckets{}
	if err := validateReportDefinition(r); err == nil {
		t.Error("Accepted report definition of type PER_DEVICE_HISTOGRAM without window_size field.")
	}

	// Add a valid window size to window_size, but also add an UNSET window size.
	r.WindowSize = []config.WindowSize{config.WindowSize_WINDOW_1_DAY, config.WindowSize_UNSET}
	if err := validateReportDefinition(r); err == nil {
		t.Error("Accepted report definition of type PER_DEVICE_HISTOGRAM with window_size field containing an UNSET window size.")
	}
}

// Test percentiles range for NUMERIC_AGGREGATION report types.
func TestValidateReportDefinitionForNumericAggregation(t *testing.T) {
	r := makeValidReport()
	r.ReportType = config.ReportDefinition_NUMERIC_AGGREGATION

	// Test that percentiles are optional.
	if err := validateReportDefinition(r); err != nil {
		t.Error("Rejected report definition of type NUMERIC_AGGREGATION with no percentiles set.")
	}

	// Test that percentiles between 0 and 100 are accepted.
	r.Percentiles = []uint32{0, 25, 50, 75, 90, 99, 100}
	if err := validateReportDefinition(r); err != nil {
		t.Error("Rejected report definition of type NUMERIC_AGGREGATION with valid percentiles.")
	}

	// Test that out of bounds percentiles are rejected.
	r.Percentiles = []uint32{0, 25, 50, 75, 100, 101}
	if err := validateReportDefinition(r); err == nil {
		t.Error("Accepted report definition of type NUMERIC_AGGREGATION with invalid percentiles.")
	}
}
