import { Command } from "https://deno.land/x/cliffy@v0.25.6/mod.ts";
import { Index } from "./src/client_search.ts";
import { Doc, DocCollector, loadDocuments } from "./src/collect.ts";

export async function collectDocuments(path: string, out: string){
    const collector = new DocCollector({ summaryOnly: true, dropContent: true });
    await collector.walkDir(path);
    const docs = collector.getDocs();
    await Deno.writeTextFile(out, JSON.stringify(docs));
}

export async function watchDocuments(doc: string , options?:{
    abort?: AbortSignal,
}){
    const doc_dump = await loadDocuments(doc);
    const collector = new DocCollector({ summaryOnly: true, dropContent: true });
    collector.setDocs(doc_dump);
    const index = Index.createIndex(doc_dump);
    async function update(){
        index.setDocs(collector.getDocs());
        await Deno.writeTextFile(doc, JSON.stringify(collector.getDocs()));
    }
    collector.watchDir(".", {
        async onAdd(doc){
            console.log("onAdd :", doc.path);
            await update();
        },
        async onRemove(path){
            console.log("onRemove :", path);
            await update();
        },
        async onChange(doc){
            console.log("onModify :", doc.path);
            await update();
        },
        abort: options?.abort,
    });
    return index;
}

export const search = new Command();
search.name("search")
.description("Search for a document.")
.command("collect", "Collect a document.")
    .description("Collect documents and index documents.")
    .arguments("<path:string>")
    .option("-o, --out <path:string>", "out file to write the index to.", {default: "collected_docs.json"})
    .action(async ({out} ,path: string) => {
        console.log("collecting", path);
        await collectDocuments(path, out);
    })
.command("search", "Search for a document.")
    .description("Search for a document.")
    .arguments("<query:string>")
    .option("-d, --docs <path:string>", "collected document file to search", {default: "collected_docs.json"})
    .action(async ({docs}, query: string) => {
        console.log("searching", query);
        const doc_dump = await loadDocuments(docs);
        const results = Index.createIndex(doc_dump).search(query);
        console.log(results);
    })
.command("interact", "watch the index and search for a document.")
    .description("watch the index and search for a document.")
    .option("-d, --doc <path:string>", "doc file to read the docs from.", {default: "collected_docs.json"})
    .action(async ({doc}) => {
        console.log("interacting");
        const index = await watchDocuments(doc);

        // interact
        while (true){
            const query = await prompt("query: ");
            if (query === null){
                continue;
            }
            if (query === ":exit"){
                break;
            }
            const results = index.search(query);
            console.log(results);
        }
    });

if ( import.meta.main ){
    await search.parse(Deno.args);
}