package main

import (
	"fmt"
	"learngo/errhandling/filelistingserver/filelisting"
	"log"
	"net/http"
	_ "net/http/pprof"
	"os"
)

// 自定义类型 ，返回 error
type appHandler func(writer http.ResponseWriter, request *http.Request) error

func errWrapper(handler appHandler) func(writer http.ResponseWriter, request *http.Request) {

	fmt.Println(" this is errWrapper func   ")

	return func(writer http.ResponseWriter, request *http.Request) {
		fmt.Println(" this is return  func   ")
		// recover  仅在defer 调用中使用
		// 获取 panice 的值
		// 如果无法处理时，可以重新 panic
		defer func() {

			if r := recover(); r != nil {
				log.Printf("panic : %v", r)
				http.Error(writer, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
			}
		}()
		err := handler(writer, request)
		if err != nil {
			log.Printf("Error handling request : %s ", err.Error())

			if userError, ok := err.(userError); ok {
				http.Error(writer, userError.Message(), http.StatusBadRequest)
				return
			}

			code := http.StatusOK
			switch {
			case os.IsNotExist(err):
				code = http.StatusNotFound
			case os.IsPermission(err):
				code = http.StatusForbidden

			default:
				code = http.StatusInternalServerError

			}
			http.Error(writer, http.StatusText(code), code)
		}
	}

}

type userError interface {
	error
	Message() string
}

func main() {
	http.HandleFunc("/", errWrapper(filelisting.FileList))
	err := http.ListenAndServe(":9999", nil)
	if err != nil {
		panic(err)
	}
}
