package rest_http

import (
	"net/http"

	"git.ali33.ru/fcg-xvii/go-tools/json"
	"git.ali33.ru/fcg-xvii/rest"
)

// Request реализует объект запроса
type Request struct {
	*http.Request
	core           any
	auth           json.Map
	data           json.Map
	files          map[string]rest.IReadCloserLen
	tokenGenerator func(json.Map, int64) (string, error)
}

func (s *Request) Type() rest.RequestType {
	return rest.RequestTypeMessage
}

func (s *Request) Root() any {
	return s.Request
}

func (s *Request) Core() any {
	return s.core
}

// GenerateToken создает новый токен авторизации. expire - timestamp даты, после которой токен не будет действителен (если указан 0 - токен бессрочный)
func (s *Request) GenerateToken(data json.Map, expire int64) (string, error) {
	return s.tokenGenerator(data, expire)
}

// Возвращает путь (краткий url) запроса
func (s *Request) Command() string {
	return s.URL.Path
}

// Data возвращает словерь json запроса
func (s *Request) Data() json.Map {
	return s.data
}

// FileKeys возвращает все имена файлы, которые доступны в запросе
func (s *Request) FileKeys() []string {
	res := make([]string, 0, len(s.files))
	for k := range s.files {
		res = append(res, k)
	}
	return res
}

// File возвращает файл, принятый в запросе multipart/form-data, если он существует
func (s *Request) File(name string) (rest.IReadCloserLen, bool) {
	r, check := s.files[name]
	return r, check
}

// Auth возвращает словарь с данными об авторизации (при условии, что в заголовке Bearer указан токен и его удалось успешно расшифровать и распарсить)
func (s *Request) Auth() json.Map {
	return s.auth
}

// IsAuth указывает, есть ли словарь авторизации или нет
func (s *Request) IsAuth() bool {
	return s.auth != nil
}

func (s *Request) SetAuth(json.Map) {}

// IsJSON возарвщвет true, если в заголовке ContentType application/json
func (s *Request) IsJSON() bool {
	return s.Header.Get("Content-Type") == "application/json"
}

// // IsForm возарвщвет true, если в заголовке ContentType multipart/form-data
func (s *Request) IsForm() bool {
	return s.Header.Get("Content-Type") == "application/x-www-form-urlencoded"
}

// Close закрывает все открытые ресурсы запоса (файлы)
func (s *Request) Close() {
	for _, file := range s.files {
		file.Close()
	}
}

func (s *Request) ResponseSuccess(data json.Map, files map[string]rest.IReadCloserLen) rest.IResponse {
	return ResponseSuccess(data, files)
}

func (s *Request) ResponseError(code int, err rest.IErrorArgs) rest.IResponse {
	return ResponseError(code, err)
}
