// 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 notify

import (
	"context"

	"go.chromium.org/luci/gae/service/datastore"

	"go.chromium.org/luci/common/data/caching/lru"
	"go.chromium.org/luci/common/errors"
	"go.chromium.org/luci/common/logging"
	"go.chromium.org/luci/server/caching"

	"go.chromium.org/luci/luci_notify/config"
	"go.chromium.org/luci/luci_notify/mailtmpl"
)

// bundle is a wrapper around mailtmpl.Bundle to provide extra info
// relevant only on server.
type bundle struct {
	*mailtmpl.Bundle
	revision string
}

// bundleCache is a in-process cache of email template bundles.
var bundleCache = caching.RegisterLRUCache(128)

// getBundle returns a bundle of all email templates for the given project.
// The returned bundle is cached in the process memory, do not modify it.
//
// Returns an error only on transient failures.
//
// Ignores an existing Datastore transaction in c, if any.
func getBundle(c context.Context, projectID string) (*bundle, error) {
	// Untie c from the current transaction.
	// What we do here has nothing to do with a possible current transaction in c.
	c = datastore.WithoutTransaction(c)

	// Fetch current revision of the project config.
	project := &config.Project{Name: projectID}
	if err := datastore.Get(c, project); err != nil {
		return nil, errors.Annotate(err, "failed to fetch project").Err()
	}

	// Lookup an existing bundle in the process cache.
	// If not available, make one and cache it.
	var transientErr error
	value, ok := bundleCache.LRU(c).Mutate(c, projectID, func(it *lru.Item) *lru.Item {
		if it != nil && it.Value.(*bundle).revision == project.Revision {
			return it // Cache hit.
		}

		// Cache miss. Either no cached value or revision mismatch.

		// Fetch all templates from the Datastore transactionally with the project.
		// On a transient error, return it and do not purge cache.
		var templateEntities []*config.EmailTemplate
		transientErr = datastore.RunInTransaction(c, func(c context.Context) error {
			templateEntities = templateEntities[:0] // txn may be retried
			if err := datastore.Get(c, project); err != nil {
				return err
			}

			q := datastore.NewQuery("EmailTemplate").Ancestor(datastore.KeyForObj(c, project))
			return datastore.GetAll(c, q, &templateEntities)
		}, nil)
		if transientErr != nil {
			return it
		}
		logging.Infof(c, "bundleCache: fetched %d email templates of project %q", len(templateEntities), projectID)

		templates := make([]*mailtmpl.Template, len(templateEntities))
		for i, t := range templateEntities {
			templates[i] = t.Template()
		}

		// Bundle all fetched templates. If bundling/parsing fails, cache the error,
		// so we don't recompile bad templates over and over.
		b := &bundle{
			revision: project.Revision,
			Bundle:   mailtmpl.NewBundle(templates),
		}

		// Cache without expiration.
		return &lru.Item{Value: b}
	})

	switch {
	case transientErr != nil:
		return nil, transientErr
	case !ok:
		panic("impossible: no cached value and no error")
	default:
		return value.(*bundle), nil
	}
}
