import bundler from "./mod.ts";
import mime from "https://esm.sh/mime@4.0.3";
import { parseArgs } from "jsr:@std/cli/parse-args";



if(Deno.mainModule == import.meta.url)
{
    serve(parseArgs(Deno.args) as ServeArgs);
}

type ServeArgs = {path?:string, html?:string, port?:string|number};
function serve(settings:ServeArgs):void
{
    let basePath = "";
    const SetDirectory =(inPath:string)=>{
        if(inPath.startsWith("http://")||inPath.startsWith("https://")||inPath.startsWith("file://"))
        {
            basePath = inPath;
        }
        else
        {
            basePath = new URL(inPath, new URL(`file://${Deno.cwd().replaceAll("\\", "/")}/`).toString()).href;
        }
        if(!basePath.endsWith("/"))
        {
            basePath = basePath + "/";
        }
        console.log("Base Path:", basePath);
    }

    SetDirectory(settings.path||"./");

    const transpiled:Map<string, string> = new Map();
    const ServeJSCode =(inText:string)=> new Response(inText, {headers:{"content-type":"application/javascript"}});
    const ServeStatic =async(inPath:string)=>
    {
        try
        {
            const handle = await fetch(basePath+inPath.substring(1));
            return new Response(handle.body, {headers:{"content-type": mime.getType(inPath)??""}})        
        }
        catch(_e)
        {
            return resp404;
        }
    };
    
    const resp404 = new Response("404", {status:404});
    let respIndex:false|Response|Promise<Response> = false;
    if(settings.html)
    {
        if(settings.html.indexOf("<") != -1)
        {
            respIndex= new Response(settings.html, {headers:{"content-type":"text-html"}});
        }
        else
        {
            respIndex = ServeStatic(settings.html);
        }
    }
    

    Deno.serve({port:parseInt(settings.port as string)||8000}, async(req)=>{
        const url = new URL(req.url);
        const index = url.pathname.lastIndexOf(".");
        if(index > -1)
        {
            const ext = url.pathname.substring(index+1);
            if(ext === "ts" || ext == "tsx" || ext == "js" || ext == "jsx")
            {
                if(ext == "js")
                {
                    const lookup = transpiled.get(url.pathname);
                    if(lookup)
                    {
                        return ServeJSCode(lookup);
                    }
                }
                else
                {
                    const lookup = transpiled.get(url.pathname.substring(0, index)+".js");
                    if(lookup)
                    {
                        return ServeJSCode(lookup);
                    }
                }
                try
                {
                    const results = await bundler({
                        entryPoints:[basePath+url.pathname],
                        outdir:"/",
                        entryNames: `[dir][name]`,
                        splitting: true
                    });
                    if(results.outputFiles)
                    {
                        results.outputFiles.forEach(output=>transpiled.set(output.path, output.text))
                        return ServeJSCode(results.outputFiles[0].text);
                    }
                    else
                    {
                        throw(new Error("no output"));
                    }
                }
                catch(_e)
                {
                    return resp404;
                }
            }
            else
            {
                return ServeStatic(url.pathname);
            }
    
        }

        if(respIndex)
        {
            return respIndex;
        }
        else
        {
            let indexLookup = url.pathname;
            if(!indexLookup.endsWith("/"))
            {
                indexLookup = indexLookup+"/";
            }
            return ServeStatic(indexLookup+"index.html");            
        }
        
    });
}

export default serve