// Code generated by go-mir. DO NOT EDIT.
// versions:
// - mir 5.3

package api

import (
	"context"
	"net/http"

	"github.com/alimy/mir/v5"
	"github.com/gin-gonic/gin"
)

type _binding_ interface {
	Bind(*gin.Context) error
}

type _render_ interface {
	Render(*gin.Context)
}

type _default_ interface {
	Bind(*gin.Context, any) error
	BindJson(*gin.Context, any) error
	Render(*gin.Context, any, error)
	RenderJson(*gin.Context, any, error)
}

type LoginReq struct {
	AgentInfo AgentInfo `json:"agent_info"`
	Name      string    `json:"name"`
	Passwd    string    `json:"passwd"`
}

type AgentInfo struct {
	Platform  string `json:"platform"`
	UserAgent string `json:"user_agent"`
}

type LoginResp struct {
	UserInfo
	ServerInfo ServerInfo `json:"server_info"`
	JwtToken   string     `json:"jwt_token"`
}

type ServerInfo struct {
	ApiVer string `json:"api_ver"`
}

type UserInfo struct {
	Name string `json:"name"`
}

type LogoutReq struct {
	AgentInfo AgentInfo `json:"agent_info"`
	Name      string    `json:"name"`
}

type TweetsReq struct {
	Date string `json:"date"`
}

type TweetsResp struct {
	Tweets []Tweet `json:"tweets"`
	Total  uint32  `json:"total"`
}

type Tweet struct {
	Type    string `json:"type"`
	Content string `json:"content"`
}

type Site interface {
	_default_

	// Chain provide handlers chain for gin
	Chain() gin.HandlersChain

	MultiAttachments(*gin.Context)
	ManyResources(*gin.Context)
	AnyStaticks(*gin.Context)
	Statics(*gin.Context)
	Assets(*gin.Context, *LoginReq) error
	SimpleUpload(*gin.Context, *LoginReq) (*LoginResp, error)
	FileUpload(*gin.Context)
	ImageUpload(*gin.Context)
	Logout(context.Context, *LogoutReq) error
	Login(context.Context, *LoginReq) (*LoginResp, error)
	PrevTweets(context.Context, *TweetsReq) (*TweetsResp, error)
	NextTweets(context.Context, *TweetsReq) (*TweetsResp, error)
	AnyTopics(context.Context) error
	Articles(context.Context) error
	Index(context.Context) error

	mustEmbedUnimplementedSiteServant()
}

type SiteChain interface {
	ChainMultiAttachments() gin.HandlersChain
	ChainSimpleUpload() gin.HandlersChain
	ChainFileUpload() gin.HandlersChain
	ChainIndex() gin.HandlersChain

	mustEmbedUnimplementedSiteChain()
}

// RegisterSiteServant register Site servant to gin
func RegisterSiteServant(e *gin.Engine, s Site, m ...SiteChain) {
	var cc SiteChain
	if len(m) > 0 {
		cc = m[0]
	} else {
		cc = &UnimplementedSiteChain{}
	}
	router := e
	// use chain for router
	middlewares := s.Chain()
	router.Use(middlewares...)

	// register routes info to router
	{
		h := append(cc.ChainMultiAttachments(), s.MultiAttachments)
		router.Handle("GET", "attachments/:name", h...)
		router.Handle("HEAD", "attachments/:name", h...)
		router.Handle("OPTIONS", "attachments/:name", h...)
	}
	{
		h := s.ManyResources
		router.Handle("GET", "resources/:name", h)
		router.Handle("HEAD", "resources/:name", h)
		router.Handle("OPTIONS", "resources/:name", h)
	}
	router.Any("anystaticks/:name", s.AnyStaticks)
	router.Handle("GET", "statics/:name", s.Statics)
	router.Handle("GET", "assets/:name", func(c *gin.Context) {
		select {
		case <-c.Request.Context().Done():
			return
		default:
		}
		req := new(LoginReq)
		if err := s.Bind(c, req); err != nil {
			s.Render(c, nil, err)
			return
		}
		s.Render(c, nil, s.Assets(c, req))
	})
	router.Handle("POST", "upload/simple/:name", append(cc.ChainSimpleUpload(), func(c *gin.Context) {
		select {
		case <-c.Request.Context().Done():
			return
		default:
		}
		req := new(LoginReq)
		if err := s.Bind(c, req); err != nil {
			s.Render(c, nil, err)
			return
		}
		resp, err := s.SimpleUpload(c, req)
		s.Render(c, resp, err)
	})...)
	router.Handle("POST", "upload/file/:name", append(cc.ChainFileUpload(), s.FileUpload)...)
	router.Handle("POST", "upload/image/:name", s.ImageUpload)
	router.Handle("POST", "user/logout", func(c *gin.Context) {
		select {
		case <-c.Request.Context().Done():
			return
		default:
		}
		req := new(LogoutReq)
		if err := s.Bind(c, req); err != nil {
			s.Render(c, nil, err)
			return
		}
		s.Render(c, nil, s.Logout(c.Request.Context(), req))
	})
	router.Handle("POST", "user/login", func(c *gin.Context) {
		select {
		case <-c.Request.Context().Done():
			return
		default:
		}
		req := new(LoginReq)
		if err := s.Bind(c, req); err != nil {
			s.Render(c, nil, err)
			return
		}
		resp, err := s.Login(c.Request.Context(), req)
		s.Render(c, resp, err)
	})
	{
		h := func(c *gin.Context) {
			select {
			case <-c.Request.Context().Done():
				return
			default:
			}
			req := new(TweetsReq)
			if err := s.Bind(c, req); err != nil {
				s.RenderJson(c, nil, err)
				return
			}
			resp, err := s.PrevTweets(c.Request.Context(), req)
			s.RenderJson(c, resp, err)
		}
		router.Handle("GET", "tweets/prev", h)
		router.Handle("HEAD", "tweets/prev", h)
		router.Handle("POST", "tweets/prev", h)
	}
	router.Any("tweets/next", func(c *gin.Context) {
		select {
		case <-c.Request.Context().Done():
			return
		default:
		}
		req := new(TweetsReq)
		if err := s.BindJson(c, req); err != nil {
			s.Render(c, nil, err)
			return
		}
		resp, err := s.NextTweets(c.Request.Context(), req)
		s.Render(c, resp, err)
	})
	router.Any("topics", func(c *gin.Context) {
		select {
		case <-c.Request.Context().Done():
			return
		default:
		}

		s.Render(c, nil, s.AnyTopics(c.Request.Context()))
	})
	router.Handle("GET", "articles/:category", func(c *gin.Context) {
		select {
		case <-c.Request.Context().Done():
			return
		default:
		}

		s.Render(c, nil, s.Articles(c.Request.Context()))
	})
	router.Handle("GET", "index", append(cc.ChainIndex(), func(c *gin.Context) {
		select {
		case <-c.Request.Context().Done():
			return
		default:
		}

		s.Render(c, nil, s.Index(c.Request.Context()))
	})...)
}

// UnimplementedSiteServant can be embedded to have forward compatible implementations.
type UnimplementedSiteServant struct{}

func (UnimplementedSiteServant) Chain() gin.HandlersChain {
	return nil
}

func (UnimplementedSiteServant) MultiAttachments(c *gin.Context) {
	c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

func (UnimplementedSiteServant) ManyResources(c *gin.Context) {
	c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

func (UnimplementedSiteServant) AnyStaticks(c *gin.Context) {
	c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

func (UnimplementedSiteServant) Statics(c *gin.Context) {
	c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

func (UnimplementedSiteServant) Assets(c *gin.Context, req *LoginReq) error {
	return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

func (UnimplementedSiteServant) SimpleUpload(c *gin.Context, req *LoginReq) (*LoginResp, error) {
	return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

func (UnimplementedSiteServant) FileUpload(c *gin.Context) {
	c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

func (UnimplementedSiteServant) ImageUpload(c *gin.Context) {
	c.String(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

func (UnimplementedSiteServant) Logout(c context.Context, req *LogoutReq) error {
	return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

func (UnimplementedSiteServant) Login(c context.Context, req *LoginReq) (*LoginResp, error) {
	return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

func (UnimplementedSiteServant) PrevTweets(c context.Context, req *TweetsReq) (*TweetsResp, error) {
	return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

func (UnimplementedSiteServant) NextTweets(c context.Context, req *TweetsReq) (*TweetsResp, error) {
	return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

func (UnimplementedSiteServant) AnyTopics(c context.Context) error {
	return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

func (UnimplementedSiteServant) Articles(c context.Context) error {
	return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

func (UnimplementedSiteServant) Index(c context.Context) error {
	return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}

func (UnimplementedSiteServant) mustEmbedUnimplementedSiteServant() {}

// UnimplementedSiteChain can be embedded to have forward compatible implementations.
type UnimplementedSiteChain struct{}

func (b *UnimplementedSiteChain) ChainMultiAttachments() gin.HandlersChain {
	return nil
}

func (b *UnimplementedSiteChain) ChainSimpleUpload() gin.HandlersChain {
	return nil
}

func (b *UnimplementedSiteChain) ChainFileUpload() gin.HandlersChain {
	return nil
}

func (b *UnimplementedSiteChain) ChainIndex() gin.HandlersChain {
	return nil
}

func (b *UnimplementedSiteChain) mustEmbedUnimplementedSiteChain() {}
