/*
 * Copyright 2026 Oleg Borodin <onborodin@gmail.com>
 */
package fileoper

import (
	"context"
	"net/http"
	"path/filepath"
	"regexp"
	"strings"

	"mstore/pkg/descr"
	"mstore/pkg/filecli"
)

// ListFiles
type ListFilesParams struct {
	Filepath string
	PathType string `param:"pathType"`
}
type ListFilesResult struct {
	Files []descr.File `json:"files,omitempty"`
}

func (oper *Operator) ListFiles(ctx context.Context, operatorID string, params *ListFilesParams) (int, *ListFilesResult, error) {
	var err error
	res := &ListFilesResult{}

	files, err := oper.listFiles(ctx, params.PathType, params.Filepath)
	if err != nil {
		code := http.StatusInternalServerError
		return code, res, err
	}
	res.Files = files
	code := http.StatusOK
	return code, res, err
}

func (oper *Operator) listFilesInCollection(ctx context.Context, collection string) ([]descr.File, error) {
	var err error
	res := make([]descr.File, 0)
	files, err := oper.mdb.ListFilesByCollection(ctx, collection)
	if err != nil {
		return res, err
	}
	res = files
	return res, err
}

func (oper *Operator) listFilesWithPrefix(ctx context.Context, prefix string) ([]descr.File, error) {
	var err error
	res := make([]descr.File, 0)
	files, err := oper.mdb.ListAllFiles(ctx)
	if err != nil {
		return res, err
	}
	for _, file := range files {
		fullpath := filepath.Join(file.Collection, file.Name)
		if strings.HasPrefix(fullpath, prefix) {
			res = append(res, file)
		}
	}
	return res, err
}

func (oper *Operator) listFilesWithRegex(ctx context.Context, regex string) ([]descr.File, error) {
	var err error
	res := make([]descr.File, 0)

	re, err := regexp.Compile(regex)
	if err != nil {
		return res, err
	}
	files, err := oper.mdb.ListAllFiles(ctx)
	if err != nil {
		return res, err
	}
	for _, file := range files {
		fullpath := filepath.Join(file.Collection, file.Name)
		if re.MatchString(fullpath) {
			res = append(res, file)
		}
	}
	return res, err
}

func (oper *Operator) listFiles(ctx context.Context, pathType, filepath string) ([]descr.File, error) {
	res := make([]descr.File, 0)
	var err error
	switch pathType {
	case filecli.PathTypeRegexp:
		files, err := oper.listFilesWithRegex(ctx, filepath)
		if err != nil {
			return res, err
		}
		res = files
	case filecli.PathTypePrefix:
		filepath, err = cleanFilepath(filepath)
		if err != nil {
			return res, err
		}
		filepath, err = cleanFilepath(filepath)
		if err != nil {
			return res, err
		}
		files, err := oper.listFilesWithPrefix(ctx, filepath)
		if err != nil {
			return res, err
		}
		res = files
	default:
		filepath, err = cleanFilepath(filepath)
		if err != nil {
			return res, err
		}
		files, err := oper.listFilesInCollection(ctx, filepath)
		if err != nil {
			return res, err
		}
		res = files
	}
	return res, err
}
