package controllers

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/gin-gonic/gin"
)

type SQLInjectionTest struct {
	name           string
	email          string
	password       string
	expectedStatus int
}

func (sit *SQLInjectionTest) SetupContext() (*gin.Context, *httptest.ResponseRecorder, *gin.Engine) {
	loginData := loginInput{
		Email:    sit.email,
		Password: sit.password,
	}
	jsonData, _ := json.Marshal(loginData)
	return GetMockedJSONContext(jsonData, "/login")
}

func (sit *SQLInjectionTest) RunHandler(c *gin.Context, router *gin.Engine) {
	router.POST("/login", Uc.LoginHandler)
	router.ServeHTTP(c.Writer, c.Request)
}

func (sit *SQLInjectionTest) ValidateResponse(w *httptest.ResponseRecorder) error {
	if sit.expectedStatus != w.Code {
		responseBody, _ := io.ReadAll(w.Body)
		return fmt.Errorf("SQL Injection Attempt: Didn't get the expected response code: got: %v; expected: %v. Context: %#v", w.Code, sit.expectedStatus, string(responseBody))
	}
	return nil
}

func (sit *SQLInjectionTest) ValidateResult() error {
	// Add any additional validation if needed
	return nil
}

func testSQLInjectionAttempt(t *testing.T) {
	tests := []SQLInjectionTest{
		{
			name:           "SQL Injection Attempt in Email",
			email:          "' OR '1'='1",
			password:       "password123",
			expectedStatus: http.StatusNotFound,
		},
		{
			name:           "SQL Injection Attempt in Password",
			email:          "user@example.com",
			password:       "' OR '1'='1",
			expectedStatus: http.StatusNotFound,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if err := runSingleTest(&tt); err != nil {
				t.Errorf("Test failed: %v", err.Error())
			}
		})
	}
}
