// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.

package resource

import (
	_ "encoding/json"
	"errors"
	"fmt"
	"github.com/xeipuuv/gojsonschema"
	"strings"
	"embed"
	"net/http"
	"log/slog"
)

//go:embed schemas/*.jsonschema
//go:embed schemas/*.schema.json
var schemaFiles embed.FS

type Schema struct {
	schema gojsonschema.JSONLoader
}

func NewSchema(name string) *Schema {
	path := fmt.Sprintf("file://schemas/%s.jsonschema", name)

	return &Schema{schema: gojsonschema.NewReferenceLoaderFileSystem(path, http.FS(schemaFiles))}
	//return &Schema{schema: gojsonschema.NewReferenceLoader(path)}
}

func (s *Schema) Validate(source string) error {
	//	loader := gojsonschema.NewGoLoader(source)
	loader := gojsonschema.NewStringLoader(source)
	result, err := gojsonschema.Validate(s.schema, loader)

	if err != nil {
		slog.Info("schema error", "source", source, "schema", s.schema, "result", result, "err",  err)
		return err
	}
	slog.Info("schema", "source", source, "schema", s.schema, "result", result, "err",  err)

	if !result.Valid() {
		schemaErrors := strings.Builder{}
		for _, err := range result.Errors() {
			schemaErrors.WriteString(err.String() + "\n")
		}
		return errors.New(schemaErrors.String())
	}
	return nil
}

func (s *Schema) ValidateSchema() error {
	sl := gojsonschema.NewSchemaLoader()
	sl.Validate = true
	schemaErr := sl.AddSchemas(s.schema)
	slog.Info("validate schema definition", "schemaloader", sl, "err", schemaErr)
	return schemaErr
}
