1//  Copyright (c) 2014 Couchbase, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// 		http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package registry
16
17import (
18	"fmt"
19
20	"github.com/blevesearch/bleve/search/highlight"
21)
22
23func RegisterFragmentFormatter(name string, constructor FragmentFormatterConstructor) {
24	_, exists := fragmentFormatters[name]
25	if exists {
26		panic(fmt.Errorf("attempted to register duplicate fragment formatter named '%s'", name))
27	}
28	fragmentFormatters[name] = constructor
29}
30
31type FragmentFormatterConstructor func(config map[string]interface{}, cache *Cache) (highlight.FragmentFormatter, error)
32type FragmentFormatterRegistry map[string]FragmentFormatterConstructor
33
34type FragmentFormatterCache struct {
35	*ConcurrentCache
36}
37
38func NewFragmentFormatterCache() *FragmentFormatterCache {
39	return &FragmentFormatterCache{
40		NewConcurrentCache(),
41	}
42}
43
44func FragmentFormatterBuild(name string, config map[string]interface{}, cache *Cache) (interface{}, error) {
45	cons, registered := fragmentFormatters[name]
46	if !registered {
47		return nil, fmt.Errorf("no fragment formatter with name or type '%s' registered", name)
48	}
49	fragmentFormatter, err := cons(config, cache)
50	if err != nil {
51		return nil, fmt.Errorf("error building fragment formatter: %v", err)
52	}
53	return fragmentFormatter, nil
54}
55
56func (c *FragmentFormatterCache) FragmentFormatterNamed(name string, cache *Cache) (highlight.FragmentFormatter, error) {
57	item, err := c.ItemNamed(name, cache, FragmentFormatterBuild)
58	if err != nil {
59		return nil, err
60	}
61	return item.(highlight.FragmentFormatter), nil
62}
63
64func (c *FragmentFormatterCache) DefineFragmentFormatter(name string, typ string, config map[string]interface{}, cache *Cache) (highlight.FragmentFormatter, error) {
65	item, err := c.DefineItem(name, typ, config, cache, FragmentFormatterBuild)
66	if err != nil {
67		if err == ErrAlreadyDefined {
68			return nil, fmt.Errorf("fragment formatter named '%s' already defined", name)
69		}
70		return nil, err
71	}
72	return item.(highlight.FragmentFormatter), nil
73}
74
75func FragmentFormatterTypesAndInstances() ([]string, []string) {
76	emptyConfig := map[string]interface{}{}
77	emptyCache := NewCache()
78	var types []string
79	var instances []string
80	for name, cons := range fragmentFormatters {
81		_, err := cons(emptyConfig, emptyCache)
82		if err == nil {
83			instances = append(instances, name)
84		} else {
85			types = append(types, name)
86		}
87	}
88	return types, instances
89}
90