package core

import (
	"github.com/doug-martin/goqu/v9"
	"github.com/doug-martin/goqu/v9/exp"
	"github.com/jackc/pgx/v5"
)

func (f *FileSystem) ReadDir(r Resource, recursive bool) ([]Resource, error) {
	return f.ReadDirDeleted(r, recursive, false)
}

func (f *FileSystem) ReadDirDeleted(r Resource, recursive, includeDeleted bool) ([]Resource, error) {
	if !r.Dir() {
		return nil, ErrResourceNotCollection
	}

	var q *goqu.SelectDataset
	if !recursive {
		_, q = selectDirectChildren(r.id, r.deleted, includeDeleted)
	} else {
		n, qq := selectResourceTree(r.id, includeDeleted)
		id := r.id
		var r exp.AliasedExpression
		q, r = selectResources(qq, n)
		q = q.Where(r.Col("id").Neq(id))
	}

	query, args, _ := q.ToSQL()
	if rows, err := f.db.Query(query, args...); err != nil {
		return nil, err
	} else {
		return pgx.CollectRows(rows, scanResourceWithoutParent)
	}
}

func (f *FileSystem) Walk(r Resource, depth int, fn func(Resource, string) error) error {
	suffix := ""
	if r.Dir() {
		suffix = "/"
	}
	err := fn(r, suffix)
	if err != nil {
		return err
	}
	if !r.Dir() || depth <= 0 {
		return nil
	}

	children, err := f.ReadDir(r, depth > 1)
	if err != nil {
		return err
	}

	// TODO: #Fix f.Walk
	for _, c := range children {
		if err := fn(c, suffix+c.Name()); err != nil {
			return err
		}
	}
	return nil
}
