//!wrt $BSPEC:{"icn":null,"cpr":"Copyright (C) Windows 96 Team 2023.","dsc":"","frn":"Indexed File System Checker","ver":1,"ssy":"cli"}

const{fixPath:fixPath}=w96.FSUtil,{getMimetypeFromPath:getMimetypeFromPath}=w96.util;let term=this.boxedEnv.term;class IFSCKApplication extends WApplication{constructor(){super()}async main(e){if(await super.main(e),!term)return;if(term.writeln("[36mIndexed File System Checker"),term.writeln("Copyright (C) SYS36.NET 2023."),term.writeln("[0m"),e.shift(),null==e[0])return term.writeln("[31mError: No drive specified to check.[0m"),1;let t=e[0];t.length>2&&(t=t.substring(0,2));const r=FS.get(t);return r?"idbfs"!==r.driverName?(term.writeln("[31mError: The target drive is not utilizing the IndexedDB FileSystem driver.[0m"),1):void await this.checkFilesystem(r):(term.writeln("[31mError: The specified drive cannot be found.[0m"),1)}async checkFilesystem(e){term.println(`A drive scan & repair will be initiated for "${e.prefix}". Please do NOT quit your session, or you may lose your data!\n`);let t=Object.keys(e._fileTable),r=0,i=0;term.println("[34mStage #1: Find and repair broken path keys[0m");for(let n of t){if(n.length>1&&(n.includes("//")||n.endsWith("/"))){const t=fixPath(n);term.println(`Fixing key ${r} [${n}] -> ${t}...`);const o={...e._fileTable[n]};delete e._fileTable[n],e._fileTable[t]=o,i++}r++}i>0?(term.println("Committing channges to FS..."),await e._sync(),term.print("\n")):term.println("No broken path keys to fix.\n");let n=0;term.println("[34mStage #2: Checking FS record data...[0m"),t=Object.keys(e._fileTable);for(let r of t)try{const t=e._fileTable[r];if(1==t.type)continue;let i=await e._getItem(t.recordId);if(!(i instanceof Blob)&&0!=t.length){if(n++,!(i instanceof Uint8Array)){term.println(`[31mrecord ${t.recordId} (belonging to ${r}) is corrupted ... deleting.[0m`),await localStorageDB.removeItem(t.recordId),delete e._fileTable[r];continue}term.println(`[33mrecord ${t.recordId} (belonging to ${r}) has wrong data type, fixing...[0m`);try{let i=await e._getItem(t.recordId);await e._setItem(t.recordId,new Blob([i],{type:getMimetypeFromPath(e.prefix+r)})),i=null,term.println(`[32mrecord ${t.recordId} (belonging to ${r}) has been fixed![0m`)}catch(e){term.println(`[31mrecord ${t.recordId} (belonging to ${r}) has NOT been fixed: ${e}[0m`)}}}catch(e){term.println(`[31mcannot fix ${ftrc.recordId} (belonging to ${r}): ${e}[0m`)}n>0?(term.println("Committing channges to FS..."),await e._sync(),term.print("\n")):term.println("All record data is OK.\n"),term.println("All done!")}}

return await WApplication.execAsync(new IFSCKApplication(), this.boxedEnv.args, this);