package routers

import (
	"exhibitionCentre/base"
	"exhibitionCentre/controllers"
	"exhibitionCentre/logging"
	"exhibitionCentre/utils"
	"io"
	"io/ioutil"
	"net/http"
)

func init() {
	// 资源
	http.Handle("/view/css/", http.StripPrefix("/view/css/", http.FileServer(http.Dir("view/css"))))
	http.Handle("/view/html/", http.StripPrefix("/view/html/", http.FileServer(http.Dir("view/html"))))
	http.Handle("/view/js/", http.StripPrefix("/view/js/", http.FileServer(http.Dir("view/js"))))
	http.Handle("/view/images/", http.StripPrefix("/view/images/", http.FileServer(http.Dir("view/images"))))
	http.Handle("/resources/", http.StripPrefix("/resources/", http.FileServer(http.Dir("resources"))))

	// http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
	// http.Handle("/view/static/", http.StripPrefix("/view/static/", http.FileServer(http.Dir("view/static"))))
	// 游客
	{
		addRouter("/", controllers.Home)
		addRouter("/test", controllers.ModelTest)
	}

	// exhibition controller
	controller := "exhibitions"
	{
		// 主页展览列表
		addRouter(routerPath(controller, ""), controllers.Exhibitions)
		// 主页更多展览列表
		addRouter(routerPath(controller, "more"), controllers.MoreExhibitions)
	}

	// exhibition controller
	controller = "exhibition"
	{
		// 展览列表页点击展览请求跳转
		addRouter(routerPath(controller, ""), controllers.GotoExhibition)
		// 获取展览详细内容
		addRouter(routerPath(controller, "detail"), controllers.ExhibitionDetail)
		// 点赞
		addRouter(routerPath(controller, "like"), controllers.ExhibitionLike)
		// 送花
		addRouter(routerPath(controller, "send_flower"), controllers.ExhibitionSendFlower)
		// 鼓掌
		addRouter(routerPath(controller, "give_applause"), controllers.ExhibitionGiveApplause)
	}

	// exhibit controller
	controller = "exhibit"
	{
		// 展品详情
		addRouter(routerPath(controller, "detail"), controllers.GetExhibitDetail)
		// 点赞
		addRouter(routerPath(controller, "like"), controllers.ExhibitLike)
		// 送花
		addRouter(routerPath(controller, "send_flower"), controllers.ExhibitSendFlower)
		// 鼓掌
		addRouter(routerPath(controller, "give_applause"), controllers.ExhibitGiveApplause)
		// 出价
		addRouter(routerPath(controller, "offer"), controllers.ExhibitOffer)
	}

	// auth
	controller = "auth"
	{
		addRouter(routerPath(controller, "sts"), controllers.AliyunSts)
	}

	// user controller
	controller = "user"
	{
		addRouter(routerPath(controller, "login"), controllers.Login)
		addRouter(routerPath(controller, "logout"), controllers.Logout)
		addRouter(routerPath(controller, "get_verification_code"), controllers.GetVerificationCode)
	}

	// manage controller
	controller = "manage"
	{
		addRouter(routerPath(controller, "dashboard"), controllers.Dashboard)

		// 展览管理
		addRouter(routerPath(controller, "dashboard/exhibitions"), controllers.DashboardExhibitions)
		addRouter(routerPath(controller, "manage_exhibitions"), controllers.ManageExhibitions)
		addRouter(routerPath(controller, "get_exhibitions"), controllers.GetExhibitions)
		addRouter(routerPath(controller, "get_publisher_exhibitions"), controllers.GetPublisherExhibitions)

		// 用户管理
		addRouter(routerPath(controller, "dashboard/users"), controllers.DashboardUsers)
		addRouter(routerPath(controller, "manage_users"), controllers.ManageUsers)
		addRouter(routerPath(controller, "get_users"), controllers.GetUsers)

		// 设置
		addRouter(routerPath(controller, "dashboard/settings"), controllers.DashboardSettings)
		addRouter(routerPath(controller, "settings"), controllers.Settings)
	}

	// manage_exhibtion
	controller = "manage_exhibitions"
	{
		addRouter(routerPath(controller, "create"), controllers.CreateExhibition)
		addRouter(routerPath(controller, "edit"), controllers.EditExhibition)
		addRouter(routerPath(controller, "update"), controllers.UpdateExhibition)
		addRouter(routerPath(controller, "delete"), controllers.DeleteExhibition)
		// 展览发布操作
		addRouter(routerPath(controller, "publish"), controllers.PublishExhibition)
		addRouter(routerPath(controller, "cancel_publish"), controllers.CancelPublishExhibition)
		// 展览场馆使用操作
		// 开幕式使用操作
		addRouter(routerPath(controller, "use_opening_ceremony"), controllers.UseOpeningCeremony)
		addRouter(routerPath(controller, "cancel_use_opening_ceremony"), controllers.CancelUseOpeningCeremony)
		// 展厅使用操作
		addRouter(routerPath(controller, "use_exhibition_hall"), controllers.UseExhibitionHall)
		addRouter(routerPath(controller, "cancel_use_exhibition_hall"), controllers.CancelUseExhibitionHall)
		// 演播厅使用操作
		addRouter(routerPath(controller, "use_studio"), controllers.UseStudio)
		addRouter(routerPath(controller, "cancel_use_studio"), controllers.CancelUseStudio)
		// 开幕式、展厅、演播厅布展操作
		addRouter(routerPath(controller, "edit_venue"), controllers.EditVenue)
		// 获取访问统计信息
		addRouter(routerPath(controller, "visit_statistics"), controllers.GetVisitStatistics)
		// 获取当前展览所有有订单的展品
		addRouter(routerPath(controller, "exhibits_with_orders"), controllers.GetExhibitsWithOrders)
		// 获取展品订单信息
		addRouter(routerPath(controller, "orders"), controllers.GetOrders)
	}

	// manage_exhibtion
	controller = "manage_exhibits"
	{
		addRouter(routerPath(controller, "edit"), controllers.EditExhibit)
		addRouter(routerPath(controller, "update"), controllers.UpdateExhibit)
		addRouter(routerPath(controller, "delete"), controllers.DeleteExhibit)
	}

	// manage_users
	controller = "manage_users"
	{
		addRouter(routerPath(controller, "add"), controllers.AddUser)
		addRouter(routerPath(controller, "delete"), controllers.DeleteUser)
	}

	// settings
	controller = "settings"
	{
		addRouter(routerPath(controller, "update"), controllers.UpdateUser)
	}
}

func addRouter(routerPath string, method func(r *base.Router) (int, []byte)) {
	http.HandleFunc(routerPath, func(w http.ResponseWriter, r *http.Request) {
		// read request body data
		body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576))
		if err != nil {
			logging.Log.Error("Read request body failed:", routerPath, err)
			utils.SendResponse(w, 500, []byte("Read request data failed."))
			return
		}
		router := base.Router{
			Writer: w,
			Req:    r,
			Data:   body,
		}

		// execute api method
		statusCode, responseData := method(&router)
		if responseData != nil {
			utils.SendResponse(w, statusCode, responseData)
		}
	})
}

func routerPath(controller, method string) string {
	if method == "" {
		return "/" + controller
	} else {
		return "/" + controller + "/" + method
	}
}
