package testhelper

import (
	"testing"

	"github.com/xeipuuv/gojsonschema"
)

func NewSchemaTestHelper(t *testing.T, schemaFile string) SchemaTestHelper {
	schema, err := getSchema(schemaFile)
	if err != nil {
		t.Fatalf(TestErrorTemplate, "RunSchemaTests", nil, err)
	}

	return SchemaTestHelper{
		schema: schema,
		t:      t,
	}
}

type SchemaTestHelper struct {
	schema *gojsonschema.Schema
	t      *testing.T
}

type SchemaTest struct {
	Name   string
	Object interface{}
}

func (h SchemaTestHelper) RunSchemaTests(tests []SchemaTest) {
	for _, test := range tests {
		h.runSchemaTest(test)
	}
}

func (h SchemaTestHelper) ValidateSchemaObject(testName string, data []byte) {
	objectLoader := gojsonschema.NewBytesLoader(data)
	h.validate(testName, objectLoader)
}

func (h SchemaTestHelper) runSchemaTest(test SchemaTest) {
	objectLoader := gojsonschema.NewGoLoader(test.Object)
	h.validate(test.Name, objectLoader)
}

func (h SchemaTestHelper) validate(testName string, objectLoader gojsonschema.JSONLoader) {
	result, err := h.schema.Validate(objectLoader)
	if err != nil {
		h.t.Fatalf(TestErrorTemplate, testName, nil, err)
	}

	if !result.Valid() {
		for _, err := range result.Errors() {
			h.t.Errorf(TestErrorTemplate, testName, nil, err)
		}
	}
}

func getSchema(filePath string) (*gojsonschema.Schema, error) {
	schemaLoader := gojsonschema.NewReferenceLoader(filePath)
	return gojsonschema.NewSchema(schemaLoader)
}
