// Copyright 2013 sigu-399 ( https://github.com/sigu-399 )
//
// 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.

// author           sigu-399
// author-github    https://github.com/sigu-399
// author-mail      sigu.399@gmail.com
//
// repository-name  gojsonschema
// repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language.
//
// description      Defines the structure of a schema.
//                  A schema can have sub-schemas.
//
// created          27-02-2013

package gojsonschema

import (
	"errors"
	"regexp"
	"strings"

	"github.com/xeipuuv/gojsonreference"
)

type jsonSchema struct {

	// basic schema meta properties
	id          *string
	title       *string
	description *string

	property string

	// Types associated with the schema
	types jsonSchemaType

	// Reference url
	ref *gojsonreference.JsonReference
	// Schema referenced
	refSchema *jsonSchema
	// Json reference
	schema *gojsonreference.JsonReference

	// hierarchy
	parent *jsonSchema

	definitions         map[string]*jsonSchema
	definitionsChildren []*jsonSchema

	itemsChildren               []*jsonSchema
	itemsChildrenIsSingleSchema bool

	propertiesChildren []*jsonSchema

	// validation : number / integer
	multipleOf       *float64
	maximum          *float64
	exclusiveMaximum bool
	minimum          *float64
	exclusiveMinimum bool

	// validation : string
	minLength *int
	maxLength *int
	pattern   *regexp.Regexp

	// validation : object
	minProperties *int
	maxProperties *int
	required      []string

	dependencies         map[string]interface{}
	additionalProperties interface{}
	patternProperties    map[string]*jsonSchema

	// validation : array
	minItems    *int
	maxItems    *int
	uniqueItems bool

	additionalItems interface{}

	// validation : all
	enum []string

	// validation : schema
	oneOf []*jsonSchema
	anyOf []*jsonSchema
	allOf []*jsonSchema
	not   *jsonSchema
}

func (s *jsonSchema) AddEnum(i interface{}) error {

	is, err := marshalToJsonString(i)
	if err != nil {
		return err
	}

	if isStringInSlice(s.enum, *is) {
		return errors.New("enum items must be unique")
	}

	s.enum = append(s.enum, *is)

	return nil
}

func (s *jsonSchema) ContainsEnum(i interface{}) (bool, error) {

	is, err := marshalToJsonString(i)
	if err != nil {
		return false, err
	}

	return isStringInSlice(s.enum, *is), nil
}

func (s *jsonSchema) AddOneOf(schema *jsonSchema) {
	s.oneOf = append(s.oneOf, schema)
}

func (s *jsonSchema) AddAllOf(schema *jsonSchema) {
	s.allOf = append(s.allOf, schema)
}

func (s *jsonSchema) AddAnyOf(schema *jsonSchema) {
	s.anyOf = append(s.anyOf, schema)
}

func (s *jsonSchema) SetNot(schema *jsonSchema) {
	s.not = schema
}

func (s *jsonSchema) AddRequired(value string) error {

	if isStringInSlice(s.required, value) {
		return errors.New("required items must be unique")
	}

	s.required = append(s.required, value)

	return nil
}

func (s *jsonSchema) AddDefinitionChild(child *jsonSchema) {
	s.definitionsChildren = append(s.definitionsChildren, child)
}

func (s *jsonSchema) AddItemsChild(child *jsonSchema) {
	s.itemsChildren = append(s.itemsChildren, child)
}

func (s *jsonSchema) AddPropertiesChild(child *jsonSchema) {
	s.propertiesChildren = append(s.propertiesChildren, child)
}

func (s *jsonSchema) PatternPropertiesString() string {

	if s.patternProperties == nil || len(s.patternProperties) == 0 {
		return "undefined" // should never happen
	}

	patternPropertiesKeySlice := []string{}
	for pk, _ := range s.patternProperties {
		patternPropertiesKeySlice = append(patternPropertiesKeySlice, `"`+pk+`"`)
	}

	if len(patternPropertiesKeySlice) == 1 {
		return patternPropertiesKeySlice[0]
	}

	return "[" + strings.Join(patternPropertiesKeySlice, ",") + "]"

}
