// Copyright 2018 johandorland ( https://github.com/johandorland )
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package gojsonschema

import (
	"bytes"
	"errors"

	"github.com/xeipuuv/gojsonreference"
)

type SchemaLoader struct {
	pool       *schemaPool
	AutoDetect bool
	Validate   bool
	Draft      Draft
}

func NewSchemaLoader() *SchemaLoader {

	ps := &SchemaLoader{
		pool: &schemaPool{
			schemaPoolDocuments: make(map[string]*schemaPoolDocument),
		},
		AutoDetect: true,
		Validate:   false,
		Draft:      Hybrid,
	}
	ps.pool.autoDetect = &ps.AutoDetect

	return ps
}

func (sl *SchemaLoader) validateMetaschema(documentNode interface{}) error {

	var (
		schema string
		err    error
	)
	if sl.AutoDetect {
		schema, _, err = parseSchemaURL(documentNode)
		if err != nil {
			return err
		}
	}

	// If no explicit "$schema" is used, use the default metaschema associated with the draft used
	if schema == "" {
		if sl.Draft == Hybrid {
			return nil
		}
		schema = drafts.GetSchemaURL(sl.Draft)
	}

	//Disable validation when loading the metaschema to prevent an infinite recursive loop
	sl.Validate = false

	metaSchema, err := sl.Compile(NewReferenceLoader(schema))

	if err != nil {
		return err
	}

	sl.Validate = true

	result := metaSchema.validateDocument(documentNode)

	if !result.Valid() {
		var res bytes.Buffer
		for _, err := range result.Errors() {
			res.WriteString(err.String())
			res.WriteString("\n")
		}
		return errors.New(res.String())
	}

	return nil
}

// AddSchemas adds an arbritrary amount of schemas to the schema cache. As this function does not require
// an explicit URL, every schema should contain an $id, so that it can be referenced by the main schema
func (sl *SchemaLoader) AddSchemas(loaders ...JSONLoader) error {
	emptyRef, _ := gojsonreference.NewJsonReference("")

	for _, loader := range loaders {
		doc, err := loader.LoadJSON()

		if err != nil {
			return err
		}

		if sl.Validate {
			if err := sl.validateMetaschema(doc); err != nil {
				return err
			}
		}

		// Directly use the Recursive function, so that it get only added to the schema pool by $id
		// and not by the ref of the document as it's empty
		if err = sl.pool.parseReferences(doc, emptyRef, false); err != nil {
			return err
		}
	}

	return nil
}

//AddSchema adds a schema under the provided URL to the schema cache
func (sl *SchemaLoader) AddSchema(url string, loader JSONLoader) error {

	ref, err := gojsonreference.NewJsonReference(url)

	if err != nil {
		return err
	}

	doc, err := loader.LoadJSON()

	if err != nil {
		return err
	}

	if sl.Validate {
		if err := sl.validateMetaschema(doc); err != nil {
			return err
		}
	}

	return sl.pool.parseReferences(doc, ref, true)
}

func (sl *SchemaLoader) Compile(rootSchema JSONLoader) (*Schema, error) {

	ref, err := rootSchema.JsonReference()

	if err != nil {
		return nil, err
	}

	d := Schema{}
	d.pool = sl.pool
	d.pool.jsonLoaderFactory = rootSchema.LoaderFactory()
	d.documentReference = ref
	d.referencePool = newSchemaReferencePool()

	var doc interface{}
	if ref.String() != "" {
		// Get document from schema pool
		spd, err := d.pool.GetDocument(d.documentReference)
		if err != nil {
			return nil, err
		}
		doc = spd.Document
	} else {
		// Load JSON directly
		doc, err = rootSchema.LoadJSON()
		if err != nil {
			return nil, err
		}
		// References need only be parsed if loading JSON directly
		//  as pool.GetDocument already does this for us if loading by reference
		err = sl.pool.parseReferences(doc, ref, true)
		if err != nil {
			return nil, err
		}
	}

	if sl.Validate {
		if err := sl.validateMetaschema(doc); err != nil {
			return nil, err
		}
	}

	draft := sl.Draft
	if sl.AutoDetect {
		_, detectedDraft, err := parseSchemaURL(doc)
		if err != nil {
			return nil, err
		}
		if detectedDraft != nil {
			draft = *detectedDraft
		}
	}

	err = d.parse(doc, draft)
	if err != nil {
		return nil, err
	}

	return &d, nil
}
