// goredo -- djb's redo implementation on pure Go
// Copyright (C) 2020-2026 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

package main

import (
	"errors"
	"fmt"
	"runtime"
)

type ErrLineErr struct {
	err      error
	file     string
	function string
	line     int
}

func (err ErrLineErr) Error() string {
	return fmt.Sprintf("%s:%d: %s: %s", err.file, err.line, err.function, err.err)
}

func (err ErrLineErr) Unwrap() error {
	return err.err
}

func ErrLine(err error) error {
	if err == nil {
		return err
	}
	pc := make([]uintptr, 10)
	n := runtime.Callers(2, pc)
	pc = pc[:n]
	frames := runtime.CallersFrames(pc)
	frame, _ := frames.Next()
	var errLine ErrLineErr
	if errors.As(err, &errLine) {
		errLine.function = frame.Function + "," + errLine.function
		return errLine
	}
	return ErrLineErr{
		err:      err,
		file:     frame.File,
		line:     frame.Line,
		function: frame.Function,
	}
}
