<?php
header('Content-Type: application/json; charset=utf-8');

require_once dirname(__DIR__) . '/config/config.php';
require_once dirname(__DIR__) . '/includes/db.php';
require_once dirname(__DIR__) . '/includes/functions.php';
require_once dirname(__DIR__) . '/includes/auth.php';

requirePermission('music_scan');

function musicUploadFolderJson($success, array $payload = [], $status = 200) {
    http_response_code((int)$status);
    echo json_encode(array_merge(['success' => (bool)$success], $payload), JSON_UNESCAPED_UNICODE);
    exit;
}

function musicUploadFolderCleanSegment($value) {
    $value = trim(ensureUtf8String($value));
    if ($value === '' || $value === '.' || $value === '..' || strpos($value, '..') !== false) {
        throw new InvalidArgumentException('사용할 수 없는 폴더명입니다.');
    }
    $value = preg_replace('/[\\\\\/:*?"<>|\x00-\x1F]+/u', ' ', $value);
    $value = preg_replace('/\s+/u', ' ', $value);
    $value = trim($value, " \t\n\r\0\x0B.");
    if ($value === '') {
        throw new InvalidArgumentException('사용할 수 없는 폴더명입니다.');
    }
    return function_exists('mb_substr') ? mb_substr($value, 0, 80, 'UTF-8') : substr($value, 0, 80);
}

function musicUploadFolderSegments($relativePath) {
    $relativePath = str_replace('\\', '/', ensureUtf8String($relativePath));
    $relativePath = trim($relativePath, " \t\n\r\0\x0B/");
    if ($relativePath === '') return [];
    if (preg_match('/^[a-z]:/i', $relativePath)) {
        throw new InvalidArgumentException('드라이브 경로는 사용할 수 없습니다.');
    }
    $segments = [];
    foreach (explode('/', $relativePath) as $segment) {
        $segment = trim($segment);
        if ($segment === '') continue;
        $segments[] = musicUploadFolderCleanSegment($segment);
    }
    return $segments;
}

function musicUploadFolderRelative(array $segments) {
    return implode('/', $segments);
}

try {
    $scanPathSetting = getScanPathSetting();
    $scanRoot = resolveFilesystemPath($scanPathSetting, 'dir') ?? toWinPath($scanPathSetting);
    if (!is_string($scanRoot) || $scanRoot === '' || !is_dir($scanRoot)) {
        throw new RuntimeException('스캔 대상 폴더를 찾을 수 없습니다.');
    }

    $segments = musicUploadFolderSegments($_GET['path'] ?? '');
    $currentDir = rtrim($scanRoot, "\\/") . (empty($segments) ? '' : DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $segments));
    if (!is_dir($currentDir) || !isPathInside($currentDir, $scanRoot)) {
        throw new RuntimeException('스캔 대상 폴더 안의 위치만 탐색할 수 있습니다.');
    }

    $folders = [];
    $items = @scandir($currentDir);
    if (is_array($items)) {
        foreach ($items as $item) {
            if ($item === '.' || $item === '..') continue;
            $item = ensureUtf8String($item);
            try {
                $cleanName = musicUploadFolderCleanSegment($item);
            } catch (Throwable $e) {
                continue;
            }
            $fullPath = $currentDir . DIRECTORY_SEPARATOR . $cleanName;
            if (!is_dir($fullPath) || !isPathInside($fullPath, $scanRoot)) continue;
            $childSegments = array_merge($segments, [$cleanName]);
            $folders[] = [
                'name' => $cleanName,
                'path' => musicUploadFolderRelative($childSegments),
            ];
        }
    }

    usort($folders, static function ($a, $b) {
        return strnatcasecmp($a['name'], $b['name']);
    });

    $parentSegments = $segments;
    array_pop($parentSegments);
    musicUploadFolderJson(true, [
        'path' => musicUploadFolderRelative($segments),
        'label' => empty($segments) ? '스캔 루트' : implode(' / ', $segments),
        'parent' => musicUploadFolderRelative($parentSegments),
        'can_go_up' => !empty($segments),
        'folders' => $folders,
        'writable' => is_writable($currentDir),
    ]);
} catch (Throwable $e) {
    musicUploadFolderJson(false, [
        'message' => $e->getMessage(),
        'path' => '',
        'label' => '스캔 루트',
        'parent' => '',
        'can_go_up' => false,
        'folders' => [],
        'writable' => false,
    ], 400);
}
