/*
 * Copyright 2026 Oleg Borodin <onborodin@gmail.com>
 *
 * This work is published and licensed under a Creative Commons
 * Attribution-NonCommercial-NoDerivatives 4.0 International License.
 *
 * Distribution of this work is permitted, but commercial use and
 * modifications are strictly prohibited.
 */
package fileoper

import (
	"context"
	"io"
	"net/http"
	"path"
	"strconv"
)

// GetFile
type GetFileParams struct {
	Filepath string
}
type GetFileResult struct {
	ContentType   string
	ContentSize   string
	ContentDigest string
	Source        io.ReadCloser

	ContentCreatedAt string
	ContentCreatedBy string
	ContentUpdatedAt string
	ContentUpdatedBy string
}

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

	xfilepath, err := cleanFilepath(params.Filepath)
	if err != nil {
		code := http.StatusInternalServerError
		return code, res, err
	}
	filename := path.Base(xfilepath)
	collection := path.Dir(xfilepath)

	resName := params.Filepath
	oper.iLock.WaitAndLock(resName)
	defer oper.iLock.Done(resName)

	descrExists, fileDescr, err := oper.mdb.GetFileByCollectionName(ctx, collection, filename)
	if err != nil {
		code := http.StatusInternalServerError
		return code, res, err
	}
	if !descrExists {
		code := http.StatusNotFound
		return code, res, err
	}
	reader, err := oper.store.GetFileReader(collection, filename)
	if err != nil {
		code := http.StatusInternalServerError
		return code, res, err
	}
	res = &GetFileResult{
		ContentSize:   strconv.FormatInt(fileDescr.Size, 10),
		ContentType:   fileDescr.Type,
		ContentDigest: fileDescr.Checksum,
		Source:        reader,

		ContentCreatedAt: fileDescr.CreatedAt,
		ContentCreatedBy: fileDescr.CreatedBy,
		ContentUpdatedAt: fileDescr.UpdatedAt,
		ContentUpdatedBy: fileDescr.UpdatedBy,
	}
	code := http.StatusOK
	return code, res, err
}
