/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 plugin

import (
	"encoding/json"
	"sync"

	"github.com/segmentfault/pacman/cache"
	"github.com/segmentfault/pacman/i18n"
	"xorm.io/xorm"

	"github.com/apache/answer/internal/base/handler"
	"github.com/apache/answer/internal/base/translator"
	"github.com/gin-gonic/gin"
)

// Data is defined here to avoid circular dependency with internal/base/data
type Data struct {
	DB    *xorm.Engine
	Cache cache.Cache
}

// GinContext is a wrapper of gin.Context
// We export it to make it easy to use in plugins
type GinContext = gin.Context

// StatusManager is a manager that manages the status of plugins
// Init Plugins:
// json.Unmarshal([]byte(`{"plugin1": true, "plugin2": false}`), &plugin.StatusManager)
// Dump Status:
// json.Marshal(plugin.StatusManager)
var StatusManager = statusManager{
	status: make(map[string]bool),
}

// Register registers a plugin
func Register(p Base) {
	registerBase(p)

	if _, ok := p.(Config); ok {
		registerConfig(p.(Config))
	}

	if _, ok := p.(UserConfig); ok {
		registerUserConfig(p.(UserConfig))
	}

	if _, ok := p.(Connector); ok {
		registerConnector(p.(Connector))
	}

	if _, ok := p.(Parser); ok {
		registerParser(p.(Parser))
	}

	if _, ok := p.(Filter); ok {
		registerFilter(p.(Filter))
	}

	if _, ok := p.(Storage); ok {
		registerStorage(p.(Storage))
	}

	if _, ok := p.(Cache); ok {
		registerCache(p.(Cache))
	}

	if _, ok := p.(UserCenter); ok {
		registerUserCenter(p.(UserCenter))
	}

	if _, ok := p.(Agent); ok {
		registerAgent(p.(Agent))
	}

	if _, ok := p.(Search); ok {
		registerSearch(p.(Search))
	}

	if _, ok := p.(Notification); ok {
		registerNotification(p.(Notification))
	}

	if _, ok := p.(Reviewer); ok {
		registerReviewer(p.(Reviewer))
	}

	if _, ok := p.(Captcha); ok {
		registerCaptcha(p.(Captcha))
	}

	if _, ok := p.(Embed); ok {
		registerEmbed(p.(Embed))
	}

	if _, ok := p.(Render); ok {
		registerRender(p.(Render))
	}

	if _, ok := p.(CDN); ok {
		registerCDN(p.(CDN))
	}

	if _, ok := p.(Importer); ok {
		registerImporter(p.(Importer))
	}

	if _, ok := p.(KVStorage); ok {
		registerKVStorage(p.(KVStorage))
	}

	if _, ok := p.(Sidebar); ok {
		registerSidebar(p.(Sidebar))
	}
}

type Stack[T Base] struct {
	plugins []T
}

type RegisterFn[T Base] func(p T)
type Caller[T Base] func(p T) error
type CallFn[T Base] func(fn Caller[T]) error

// MakePlugin creates a plugin caller and register stack manager
// The parameter super presents if the plugin can be disabled.
// It returns a register function and a caller function
// The register function is used to register a plugin, it will be called in the plugin's init function
// The caller function is used to call all registered plugins
func MakePlugin[T Base](super bool) (CallFn[T], RegisterFn[T]) {
	stack := Stack[T]{}

	call := func(fn Caller[T]) error {
		for _, p := range stack.plugins {
			// If the plugin is disabled, skip it
			if !super && !StatusManager.IsEnabled(p.Info().SlugName) {
				continue
			}

			if err := fn(p); err != nil {
				return err
			}
		}
		return nil
	}

	register := func(p T) {
		for _, plugin := range stack.plugins {
			if plugin.Info().SlugName == p.Info().SlugName {
				panic("plugin " + p.Info().SlugName + " is already registered")
			}
		}
		stack.plugins = append(stack.plugins, p)
	}

	return call, register
}

type statusManager struct {
	lock   sync.Mutex
	status map[string]bool
}

func (m *statusManager) Enable(name string, enabled bool) {
	m.lock.Lock()
	defer m.lock.Unlock()
	if !enabled {
		m.status[name] = enabled
		return
	}
	m.status[name] = enabled

	for _, slugName := range coordinatedCaptchaPlugins(name) {
		m.status[slugName] = false
	}

	for _, slugName := range coordinatedCDNPlugins(name) {
		m.status[slugName] = false
	}
}

func (m *statusManager) IsEnabled(name string) bool {
	if status, ok := m.status[name]; ok {
		return status
	}
	return false
}

// MarshalJSON implements the json.Marshaler interface.
func (m *statusManager) MarshalJSON() ([]byte, error) {
	return json.Marshal(m.status)
}

// UnmarshalJSON implements the json.Unmarshaler interface.
func (m *statusManager) UnmarshalJSON(data []byte) error {
	return json.Unmarshal(data, &m.status)
}

// Translate translates the key to the current language of the context
func Translate(ctx *GinContext, key string) string {
	return translator.Tr(handler.GetLangByCtx(ctx), key)
}

// TranslateWithData translates the key to the language with data
func TranslateWithData(lang i18n.Language, key string, data any) string {
	return translator.TrWithData(lang, key, data)
}

// TranslateFn presents a generator of translated string.
// We use it to delegate the translation work outside the plugin.
type TranslateFn func(ctx *GinContext) string

// Translator contains a function that translates the key to the current language of the context
type Translator struct {
	Fn TranslateFn
}

// MakeTranslator generates a translator from the key
func MakeTranslator(key string) Translator {
	t := func(ctx *GinContext) string {
		return Translate(ctx, key)
	}
	return Translator{Fn: t}
}

// Translate translates the key to the current language of the context
func (t Translator) Translate(ctx *GinContext) string {
	if t.Fn == nil {
		return ""
	}
	return t.Fn(ctx)
}
