/**
 * This script redraws the default lighttpd directory listing to our custom styles.
 * 
 * Since the person inserting the files has physical access to the box and we serve
 * their static sites directly from the USB, ***THIS SCRIPT DOES NOT ATTEMPT TO PREVENT
 * INJECTION ATTACKS***.  We just pop filenames and the like right into innerHTML.
 */


const supported_extensions = ["apk", "deb", "dmg", "pdf", "exe", "jpg", "png", "pptx", "ppt", "mp3"];
const usbRoot = "usb-butter/";
const inferredBaseURL = window.location.pathname.split("/" + usbRoot)[0] + "/";

// Don't display these in the dirlisting; they get first-class treatment
// on the homepage.
const foldersToHide = ["appstore", "osm-map-files"];

const getFolderDivHTML = (directory_name, number_of_items, href) => {
    return `
    <a class="filerow" href="${href}">
        <div class="logo-filerow">
            <img src="${inferredBaseURL}assets/images/directory.svg" alt="directory">
        </div>
        <div class="text-filerow">
            <div class="upper-text">${directory_name}</div>
            <div class="lower-text"><span id="${href}">${number_of_items}</span> items</div>
        </div>
        <div class="dl-block"></div>
    </a>`;
};

const getFileDivHTML = (file_name, size, date, href) => {
    icon = "ext-unknown.svg";
    extension = file_name.split('.').pop();
    if (supported_extensions.includes(extension)) {
        icon = "ext-" + extension + ".svg";
    }
    // turn date from "2021-09-01 12:34:56" to "Sep 1, 2021"
    date = new Date(date).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
    return `
    <div class="filerow">
        <a href="${href}" class="logo-filerow">
            <img src="${inferredBaseURL}assets/images/${icon}" alt="directory">
        </a>
        <a href="${href}" class="text-filerow">
            <div class="upper-text">${file_name}</div>
            <div class="lower-text">${size} | ${date}</div>
        </a>
        <a href="${href}" download="${file_name}">
            <div class="dl-block">
                <img src="${inferredBaseURL}assets/images/download-icon.svg" alt="download">
            </div>
        </a>
    </div>
    `;
};

const getFolderItemCount = async (folder_href) => {
    async function populateSpan(response) {
        if (!response.ok) {
            console.error("Failed to fetch " + folder_href);
            return;
        }
        const text = await response.text();
        const doc = new DOMParser().parseFromString(text, 'text/html');
        const { files, folders } = extractDirectoryListing(doc);
        const items = files.length + folders.length;
        const span = document.getElementById(folder_href);
        span.textContent = items;
    }
    const response = fetch(folder_href).then(populateSpan);
}

// Function to extract directory listing information
function extractDirectoryListing(doc) {
    // Get all rows in the table body
    const rows = doc.querySelectorAll('tbody tr');

    // Initialize arrays to hold file and folder information
    const files = [];
    const folders = [];

    // Iterate over each row
    rows.forEach(row => {
        const nameCell = row.querySelector('td.n a');
        const modifiedCell = row.querySelector('td.m');
        const sizeCell = row.querySelector('td.s');
        const typeCell = row.querySelector('td.t');

        const name = nameCell.textContent;
        const lastModified = modifiedCell.textContent.trim();
        const size = sizeCell.textContent.trim();
        const type = typeCell.textContent.trim();
        const href = nameCell.getAttribute('href');

        // Determine if it's a file or folder based on the class of the row or type
        if (type === 'Directory') {
            if (name !== '..' && !foldersToHide.includes(name)) {
                folders.push({
                    name: name.replace('/', ''),  // Remove the trailing slash
                    lastModified: lastModified,
                    size: size,
                    type: type,
                    href: href
                });
            }
        } else {
            if (!name.startsWith('.')) {
                files.push({
                    name: name,
                    lastModified: lastModified,
                    size: size,
                    type: type,
                    href: href
                });
            }
        }
    });

    return { files, folders };
}

function renderDirectory() {
    const { files, folders } = extractDirectoryListing(window.document);
    const listDiv = document.querySelector('div.list');

    // Header with breadcrumbs
    const h2Path = document.querySelector('h2').textContent;
    const path = h2Path.replace('Index of ', '').replace(usbRoot, '');

    const breadcrumbs = document.createElement("div");
    breadcrumbs.classList.add('breadcrumbs');
    let breadcrumbHTML = `
        <a href="${inferredBaseURL}" class="crumb"><img class="home-icon" src="${inferredBaseURL}assets/images/home.svg" alt="home"></a>
        <a href="${inferredBaseURL}${usbRoot}" class="crumb"><img class="path-next" src="${inferredBaseURL}assets/images/next.svg">Explore</a>
    `;
    const pathSteps = path.split('/');
    let thisDirsName = "Explore";
    let pathToHere = usbRoot;
    pathSteps.forEach((step, index) => {
        if (step !== "") {
            pathToHere += step + '/';
            thisDirsName = step;
            breadcrumbHTML += `
            <a href="${inferredBaseURL}${pathToHere}" class="crumb"><img class="path-next" src="${inferredBaseURL}assets/images/next.svg">${step}</a>`;
        }
    });
    breadcrumbs.innerHTML = breadcrumbHTML;
    listDiv.parentNode.insertBefore(breadcrumbs, listDiv);

    // hr
    const fullWithHR = document.createElement('hr');
    fullWithHR.classList.add('full-width');
    listDiv.parentNode.insertBefore(fullWithHR, listDiv);

    // Secondary header
    const secondaryHeader = document.createElement('div');
    secondaryHeader.classList.add('breadcrumb-name');
    secondaryHeader.innerHTML = `<a href="../"><img class="back" src="${inferredBaseURL}assets/images/next.svg"></a>`;
    secondaryHeader.innerHTML += `${thisDirsName}`;
    listDiv.parentNode.insertBefore(secondaryHeader, listDiv);

    // Create a folder listing
    const folderListing = document.createElement("div");
    folderListing.classList.add('folder-list');
    if (folders.length > 0) {
        folderListing.innerHTML = '<h2>Folders</h2>';
    }

    // for each folder, add a div to folderListing
    folders.forEach(folder => {
        const folderDiv = document.createElement('div');
        folderDiv.classList.add('folder-row');
        folderDiv.innerHTML = getFolderDivHTML(folder.name, "?", folder.href);
        folderListing.appendChild(folderDiv);
        getFolderItemCount(folder.href);
    });

    // do the insertion
    listDiv.parentNode.insertBefore(folderListing, listDiv);

    if (folders.length > 0 && files.length > 0) {
        listDiv.parentNode.insertBefore(document.createElement('hr'), listDiv);
    }

    // then for files
    const fileListing = document.createElement("div");
    fileListing.classList.add('file-list');
    if (files.length > 0) {
        fileListing.innerHTML = '<h2>Files</h2>';
    }

    // for each file, add a div to fileListing
    files.forEach(file => {
        const fileDiv = document.createElement('div');
        fileDiv.classList.add('file-row');
        fileDiv.innerHTML = getFileDivHTML(file.name, file.size, file.lastModified, file.href);
        fileListing.appendChild(fileDiv);
    });

    // do the insertion
    listDiv.parentNode.insertBefore(fileListing, listDiv);
}

window.onload = function () {
    if (window.location.pathname.includes(usbRoot)) {
        renderDirectory();
    }
}