// Copyright 2018 The LUCI Authors.
//
// 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 builtins

import (
	"regexp"
	"sync"

	"go.starlark.net/starlark"
)

// RegexpMatcher returns a function (with given name) that allows Starlark code
// to do regular expression matches:
//
//  def submatches(pattern, str):
//    """Returns a tuple of submatches with the leftmost match of the regular
//    expression.
//
//    The returned tuple has the full match as a first item, followed by
//    subexpression matches.
//
//    If the string doesn't match the expression returns an empty tuple. Fails if
//    the regular expression can't be compiled.
//    """
//
// Uses Go regexp engine, which is slightly different from Python's. API also
// explicitly does NOT try to mimic Python's 're' module.
//
// Each separate instance of the builtin holds a cache of compiled regular
// expressions internally. The cache is never cleaned up. Errors are not cached,
// since we don't expect to see them often.
//
// Safe for concurrent use.
func RegexpMatcher(name string) *starlark.Builtin {
	cache := regexpCache{r: make(map[string]*regexp.Regexp)}
	return starlark.NewBuiltin(name, func(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
		var pattern, str starlark.String
		err := starlark.UnpackArgs(name, args, kwargs,
			"pattern", &pattern,
			"str", &str,
		)
		if err != nil {
			return nil, err
		}
		groups, err := cache.matches(pattern.GoString(), str.GoString())
		if err != nil {
			return nil, err
		}
		tup := make(starlark.Tuple, len(groups))
		for i, s := range groups {
			tup[i] = starlark.String(s)
		}
		return tup, nil
	})
}

type regexpCache struct {
	m sync.RWMutex
	r map[string]*regexp.Regexp
}

func (c *regexpCache) matches(pat, str string) ([]string, error) {
	exp, err := c.exp(pat)
	if err != nil {
		return nil, err
	}
	return exp.FindStringSubmatch(str), nil
}

func (c *regexpCache) exp(pat string) (*regexp.Regexp, error) {
	c.m.RLock()
	exp, _ := c.r[pat]
	c.m.RUnlock()
	if exp != nil {
		return exp, nil
	}

	c.m.Lock()
	defer c.m.Unlock()
	if exp, _ = c.r[pat]; exp != nil {
		return exp, nil
	}

	exp, err := regexp.Compile(pat)
	if err != nil {
		return nil, err
	}
	c.r[pat] = exp
	return exp, nil
}
