package main

import (
	"fmt"
	"os"
	"strconv"
	"strings"
)

// TestData представляет тестовые данные
type TestData struct {
	ID        any    `json:"id"`
	Name      string `json:"name"`
	Age       int    `json:"age"`
	Value     *int   `json:"value,omitempty"`
	UserID    int    `json:"userId"`
	Timestamp int64  `json:"timestamp"`
}

// TestUser представляет пользователя
type TestUser struct {
	ID        int    `json:"id"`
	Username  string `json:"username"`
	Password  string `json:"password"`
	IsActive  bool   `json:"isActive"`
	Role      string `json:"role"`
	Timestamp int64  `json:"timestamp"`
}

// TestOrder представляет заказ
type TestOrder struct {
	ID        int     `json:"id"`
	UserID    int     `json:"userId"`
	Status    string  `json:"status"`
	Amount    float64 `json:"amount"`
	Timestamp int64   `json:"timestamp"`
}

func main() {
	// Очищаем тестовую папку
	os.RemoveAll("./data/test-linedb-delete")

	fmt.Println("=== LineDb Delete Operations Demo ===")

	// Получаем номера тестов из аргументов командной строки
	testNumbers := parseTestNumbers()

	// Выполняем тесты
	if len(testNumbers) == 0 {
		// Если номера не указаны, выполняем все тесты
		runAllTests()
	} else {
		// Выполняем только указанные тесты
		runSelectedTests(testNumbers)
	}

	fmt.Println("\n=== Все тесты завершены ===")
}

// parseTestNumbers парсит номера тестов из аргументов командной строки
func parseTestNumbers() []int {
	if len(os.Args) < 2 {
		return []int{}
	}

	// Получаем аргумент после имени программы
	arg := os.Args[1]

	// Проверяем, что это не флаг помощи
	if arg == "-h" || arg == "--help" || arg == "help" {
		printUsage()
		return []int{}
	}

	// Разбиваем по запятой
	parts := strings.Split(arg, ",")
	var numbers []int

	for _, part := range parts {
		part = strings.TrimSpace(part)
		if part == "" {
			continue
		}

		num, err := strconv.Atoi(part)
		if err != nil {
			fmt.Printf("Ошибка: '%s' не является числом\n", part)
			printUsage()
			return []int{}
		}

		// Проверяем диапазон
		if num < 1 || num > 8 {
			fmt.Printf("Ошибка: номер теста %d должен быть от 1 до 8\n", num)
			printUsage()
			return []int{}
		}

		numbers = append(numbers, num)
	}

	return numbers
}

// printUsage выводит справку по использованию
func printUsage() {
	fmt.Println("\nИспользование:")
	fmt.Println("  go run main.go                    # Запустить все тесты")
	fmt.Println("  go run main.go 1                  # Запустить только тест 1")
	fmt.Println("  go run main.go 1,3                # Запустить тесты 1 и 3")
	fmt.Println("  go run main.go 2,3,4              # Запустить тесты 2, 3 и 4")
	fmt.Println("  go run main.go help               # Показать эту справку")
	fmt.Println("\nДоступные тесты:")
	fmt.Println("  1 - Удаление одной записи по ID")
	fmt.Println("  2 - Удаление одной записи по текстовому фильтру")
	fmt.Println("  3 - Удаление нескольких записей по массиву данных")
	fmt.Println("  4 - Удаление записей по частичному совпадению")
	fmt.Println("  5 - Удаление записей из партиционированных коллекций")
	fmt.Println("  6 - Удаление записей с граничными случаями")
	fmt.Println("  7 - Удаление записей с производительностью")
	fmt.Println("  8 - Удаление записей с множественными коллекциями")
	os.Exit(0)
}

// runAllTests запускает все тесты
func runAllTests() {
	testDeleteOneRecordByID()
	testDeleteOneRecordByTextFilter()
	testDeleteMultipleRecordsByArray()
	testDeleteByPartialMatch()
	testDeleteFromPartitionedCollections()
	testDeleteEdgeCases()
	testDeletePerformance()
	testDeleteMultipleCollections()
}

// runSelectedTests запускает только выбранные тесты
func runSelectedTests(numbers []int) {
	for _, num := range numbers {
		switch num {
		case 1:
			fmt.Println("1. Удаление одной записи по ID")
			testDeleteOneRecordByID()
		case 2:
			fmt.Println("2. Удаление одной записи по текстовому фильтру")
			testDeleteOneRecordByTextFilter()
		case 3:
			fmt.Println("3. Удаление нескольких записей по массиву данных")
			testDeleteMultipleRecordsByArray()
		case 4:
			fmt.Println("4. Удаление записей по частичному совпадению")
			testDeleteByPartialMatch()
		case 5:
			fmt.Println("5. Удаление записей из партиционированных коллекций")
			testDeleteFromPartitionedCollections()
		case 6:
			fmt.Println("6. Удаление записей с граничными случаями")
			testDeleteEdgeCases()
		case 7:
			fmt.Println("7. Удаление записей с производительностью")
			testDeletePerformance()
		case 8:
			fmt.Println("8. Удаление записей с множественными коллекциями")
			testDeleteMultipleCollections()
		}
	}
}
