package config_validator

import (
	"config"
	"config_parser"
	"fmt"
	"testing"

	"github.com/google/go-cmp/cmp"
)

func TestEmptyValidationErrors(t *testing.T) {
	if newValidationErrors("err").err() != nil {
		t.Errorf("Empty validation errors .err() should return nil")
	}
}

func TestSingleValidationErrors(t *testing.T) {
	errs := newValidationErrors("err")
	errs.addError("an", fmt.Errorf("error"))
	expectedError := "err `an`: error"
	if diff := cmp.Diff(errs.err().Error(), expectedError); diff != "" {
		t.Errorf("Output error does not match expected error: %s", diff)
	}
}

func TestMultipleValidationErrors(t *testing.T) {
	errs := newValidationErrors("err")
	errs.addError("an", fmt.Errorf("error"))
	errs.addError("another", fmt.Errorf("error"))
	expectedError := "err `an`: error\nerr `another`: error"
	if diff := cmp.Diff(errs.err().Error(), expectedError); diff != "" {
		t.Errorf("Output error does not match expected error: %s", diff)
	}
}

func TestNestedValidationErrors(t *testing.T) {
	innerErr := newValidationErrors("inner")
	innerErr.addError("an", fmt.Errorf("error"))
	errs := newValidationErrors("err")
	errs.addError("nested", innerErr.err())
	expectedError := "err `nested`:\n  inner `an`: error"
	if diff := cmp.Diff(errs.err().Error(), expectedError); diff != "" {
		t.Errorf("Output error does not match expected error: %s", diff)
	}
}

func TestMultipleNestedValidationErrors(t *testing.T) {
	innerErr := newValidationErrors("inner")
	innerErr.addError("an", fmt.Errorf("error"))
	errs := newValidationErrors("err")
	errs.addError("nested2", innerErr.err())
	errs.addError("nested1", innerErr.err())
	expectedError := "err `nested1`:\n  inner `an`: error\nerr `nested2`:\n  inner `an`: error"
	if diff := cmp.Diff(errs.err().Error(), expectedError); diff != "" {
		t.Errorf("Output error does not match expected error: %s", diff)
	}
}

func TestMultipleErrorsForLevel(t *testing.T) {
	errs := newValidationErrors("err")
	errs.addError("an", fmt.Errorf("error"))
	errs.addError("an", fmt.Errorf("error"))
	expectedError := "err `an`:\n  error\n  error"
	if diff := cmp.Diff(errs.err().Error(), expectedError); diff != "" {
		t.Errorf("Output error does not match expected error: %s", diff)
	}
}

func TestValidateProjectConfigDatasVersion(t *testing.T) {
	projectConfigFile := config.ProjectConfigFile{
		MetricDefinitions: []*config.MetricDefinition{
			{
				CustomerId:     5,
				ProjectId:      3,
				MetricName:     "the_metric_name",
				Id:             1,
				TimeZonePolicy: config.MetricDefinition_UTC,
				Reports: []*config.ReportDefinition{
					{
						ReportName: "the_report",
						Id:         10,
						ReportType: config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS,
					},
					{
						ReportName: "the_other_report",
						Id:         20,
						ReportType: config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS,
					},
				},
			},
		},
	}
	configs := []config_parser.ProjectConfigData{
		{
			CustomerName:      "customer5",
			CustomerId:        5,
			ProjectName:       "project3",
			ProjectId:         3,
			Contact:           "project3@customer5.com",
			CobaltVersion:     config_parser.CobaltVersion0,
			ProjectConfigFile: &projectConfigFile,
		},
	}
	err := ValidateProjectConfigDatas(configs)
	if err == nil {
		t.Errorf("Validation did not catch expected error for cobalt version")
	}
}

func TestValidateProjectConfigDatasCustomerExperimentNamespaces(t *testing.T) {
	configs := []config_parser.ProjectConfigData{
		{
			CustomerName:                  "cobalt_internal",
			CustomerId:                    2147483647,
			ProjectName:                   "project3",
			ProjectId:                     3,
			Contact:                       "project3@customer5.com",
			CobaltVersion:                 config_parser.CobaltVersion1,
			CustomerExperimentsNamespaces: []interface{}{"customer_experiment_namespace"},
		},
	}
	err := ValidateProjectConfigDatas(configs)
	if err == nil {
		t.Errorf("Validation did not catch expected error for experiments in internal customers")
	}
}

func TestValidateProjectConfigDatasProjectExperimentNamespaces(t *testing.T) {
	configs := []config_parser.ProjectConfigData{
		{
			CustomerName:                 "cobalt_internal",
			CustomerId:                   2147483647,
			ProjectName:                  "project3",
			ProjectId:                    3,
			Contact:                      "project3@customer5.com",
			CobaltVersion:                config_parser.CobaltVersion1,
			ProjectExperimentsNamespaces: []interface{}{"customer_experiment_namespace"},
		},
	}
	err := ValidateProjectConfigDatas(configs)
	if err == nil {
		t.Errorf("Validation did not catch expected error for experiments in internal projects")
	}
}

func TestValidateProjectConfigDatasDeletedProject(t *testing.T) {
	projectConfigFile := config.ProjectConfigFile{
		MetricDefinitions: []*config.MetricDefinition{
			{
				CustomerId:     5,
				ProjectId:      3,
				MetricName:     "the_metric_name",
				Id:             1,
				TimeZonePolicy: config.MetricDefinition_UTC,
				Reports: []*config.ReportDefinition{
					{
						ReportName: "the_report",
						Id:         10,
						ReportType: config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS,
					},
					{
						ReportName: "the_other_report",
						Id:         20,
						ReportType: config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS,
					},
				},
			},
		},
	}
	configs := []config_parser.ProjectConfigData{
		{
			CustomerName:      "customer5",
			CustomerId:        5,
			ProjectName:       "project3",
			ProjectId:         3,
			Contact:           "project3@customer5.com",
			CobaltVersion:     config_parser.CobaltVersion1,
			DeletedProjectIds: []uint32{4, 5},
			ProjectConfigFile: &projectConfigFile,
		},
		{
			CustomerName:      "customer5",
			CustomerId:        5,
			ProjectName:       "project4",
			ProjectId:         4,
			Contact:           "project4@customer5.com",
			CobaltVersion:     config_parser.CobaltVersion1,
			DeletedProjectIds: []uint32{4, 5},
			ProjectConfigFile: &projectConfigFile,
		},
	}
	err := ValidateProjectConfigDatas(configs)
	if err == nil {
		t.Errorf("Validation did not catch expected error for reusing deleted project ID")
	}
}

func TestValidateProjectConfigDatasDeletedMetric(t *testing.T) {
	projectConfigFile := config.ProjectConfigFile{
		MetricDefinitions: []*config.MetricDefinition{
			{
				CustomerId:     5,
				ProjectId:      3,
				MetricName:     "the_metric_name",
				Id:             1,
				TimeZonePolicy: config.MetricDefinition_UTC,
				Reports: []*config.ReportDefinition{
					{
						ReportName: "the_report",
						Id:         10,
						ReportType: config.ReportDefinition_FLEETWIDE_OCCURRENCE_COUNTS,
					},
					{
						ReportName: "the_other_report",
						Id:         20,
						ReportType: config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS,
					},
				},
			},
			{
				CustomerId:     5,
				ProjectId:      3,
				MetricName:     "the_other_metric_name",
				Id:             2,
				TimeZonePolicy: config.MetricDefinition_LOCAL,
				Reports: []*config.ReportDefinition{
					{
						ReportName: "the_report",
						Id:         10,
						ReportType: config.ReportDefinition_HOURLY_VALUE_NUMERIC_STATS,
					},
				},
			},
		},
		DeletedMetricIds: []uint32{2},
	}
	configs := []config_parser.ProjectConfigData{
		{
			CustomerName:      "customer5",
			CustomerId:        5,
			ProjectName:       "project3",
			ProjectId:         3,
			Contact:           "project3@customer5.com",
			CobaltVersion:     config_parser.CobaltVersion1,
			ProjectConfigFile: &projectConfigFile,
		},
	}
	err := ValidateProjectConfigDatas(configs)
	if err == nil {
		t.Errorf("Validation did not catch expected error for reusing deleted metric ID")
	}
}
