// SPDX-License-Identifier: AGPL-3.0-only
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, version 3.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>

package recovery

import (
	"errors"
	"fmt"

	"github.com/labstack/echo/v4"
	"go.uber.org/zap"

	"github.com/bangumi/server/config/env"
	"github.com/bangumi/server/internal/pkg/logger"
)

var errInternal = errors.New("internal server error")

// New creates a new middleware handler.
func New() echo.MiddlewareFunc {
	if !env.Production {
		return dev()
	}

	// Set default config
	log := logger.Named("http.recovery")
	// Return new handler
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) (err error) {
			defer func() {
				if r := recover(); r != nil {
					log.Error("recovery", zap.Any("recovery", r), logger.Ctx(c.Request().Context()))

					var ok bool
					if err, ok = r.(error); !ok {
						// Set error that will call the global error handler
						err = fmt.Errorf("%w: %v", errInternal, r)
					}
				}
			}()

			// Return errInternal if exist, else move to next handler
			return next(c)
		}
	}
}
