// ==================== |------| ====================
// ==================== | DuSI | ====================
// ==================== |------| ====================

(function(thisObj) {

// ==================== |------| ====================
// ==================== | core | ====================
// ==================== |------| ====================

// ==================== |---------| ====================
// ==================== | license | ====================
// ==================== |---------| ====================

/* License
	DuSI - Adobe System Info

    This program uses DuESF, the Duduf ExtendScript Framework.

	Copyright (c) 2022 Nicolas Dufresne and contributors

	This file is part of DuSI.

		This program is free software: you can redistribute it and/or modify
		it under the terms of the GNU General Public License as published by
		the Free Software Foundation, either version 3 of the License, or
		(at your option) any later version.

		This program is distributed in the hope that it will be useful,
		but WITHOUT ANY WARRANTY; without even the implied warranty of
		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
		GNU General Public License for more details.

		You should have received a copy of the GNU General Public License
		along with this program. If not, see <http://www.gnu.org/licenses/>.

*/
// ==================== |-------| ====================
// ==================== | setup | ====================
// ==================== |-------| ====================

// ==================== |---------| ====================
// ==================== | version | ====================
// ==================== |---------| ====================

var scriptName = "DuSI";
var scriptVersion = "1.4.0";
var scriptAbout = 'Collect system information.';
var companyName = "RxLaboratory";

var chatURL = 'http://chat.rxlab.info';
var bugReportURL = '';
var featureRequestURL = '';
var aboutURL = '/';
var docURL = '';
var companyURL = 'https://rxlaboratory.org';
var rxVersionURL = 'http://api.rxlab.io';
// ==================== |------| ====================
// ==================== | main | ====================
// ==================== |------| ====================

// FUNCTIONS

function getFolder(f) {
    if (!(f instanceof Folder)) f = new Folder(f);
    if (!f.exists) return null;
    else return f;
}

function fsName(f) {
    if (f instanceof Folder) return f.fsName;
    else if (f != null && f !== undefined) return f;
    return "not found";
}

function isFile(f) { return f instanceof File; }

function isFolder(f) { return f instanceof Folder; }

function canRead(folder) {
    folder = getFolder(folder);
    if ( !folder ) return false;

    // Try to list files
    try {
        f = folder.getFiles( isFile );
        /*if (f.length > 0) {
            if (f[0].open('r')){
                f.read();
                f.close();
                return true;
            }
            return false;
        }//*/
        return true;
    }
    catch (e) { return false; }
}

function canWrite(folder) {
    folder = getFolder(folder);
    if ( !folder ) return false;

    var content = 'test-write-access';
    var f = new File(folder.absoluteURI + '/' + content);

    if (f.open('w')) {
        try {
            f.write(content);
            f.close();
            f.remove();
            return true;
        }
        catch(e) { return false };
    } else return false;
}

function getSysInfo() {

    // Check write access
    function checkAccess(f) {
        var r = f;
        r += ' # [';
        r += canRead(f) ? 'R' : '-';
        r += ',';
        r += canWrite(f) ? 'W' : '-';
        r += ']';
        return r;
    }

    // Ask for file name
    var saveFile = File.saveDialog("Save system info to...", "Text file: *.txt");

    var appData = fsName(Folder.appData);
    var appPackage = fsName(Folder.appPackage);
    var commonFiles = fsName(Folder.commonFiles);
    var current = fsName(Folder.current);
    var desktop = fsName(Folder.desktop);
    var myDocuments = fsName(Folder.myDocuments);
    var startup = fsName(Folder.startup);
    var system = fsName(Folder.system);
    var temp = fsName(Folder.temp);
    var userData = fsName(Folder.userData);

    var host = BridgeTalk.appName;
    var hostVersion = BridgeTalk.appVersion;
    if (host == 'aftereffects') hostVersion = app.version;

    var sysInfo = [ 'Generated by DuSI v' + scriptVersion,
        '\n[OS]',
        'OS:' + $.os,
        'Filesystem:' + Folder.fs,
        '\n[Host]',
        'Host:' + host,
        'HostVersion:' + hostVersion,
        '\n[Folders]',
        'appData:' + checkAccess(appData),
        'appPackage:' + checkAccess(appPackage),
        'commonFiles:' + checkAccess(commonFiles),
        'current:' + checkAccess(current),
        'desktop:' + checkAccess(desktop),
        'myDocuments:' + checkAccess(myDocuments),
        'startup:' + checkAccess(startup),
        'system:' + checkAccess(system),
        'temp:' + checkAccess(temp),
        'userData:' + checkAccess(userData)
    ].join('\n');

    if (saveFile.open('w')) {
        saveFile.write(sysInfo);
        saveFile.close();
    }
    else {
        alert("Sorry, I can't create the system info file. Here's the collected data: \n\n" + sysInfo);
    }
}

function openURL(url) {
    if (BridgeTalk.appName == 'aftereffects') {
        if ( $.os.toLowerCase().indexOf( "mac" ) >= 0) system.callSystem( 'open "' + url + '"' );
        else system.callSystem( 'explorer "' + url + '"' );
        return;
    }
    var timestamp = Date.now();
    var shortcut = new File(Folder.temp + '/duesf_shortcut_' + timestamp + '.url');
    shortcut.open('w');
    shortcut.writeln('[InternetShortcut]');
    shortcut.writeln('URL=' + url);
    shortcut.writeln();
    shortcut.close();
    shortcut.execute();
    shortcut.remove();
}

function wipeScripts() {

    var scriptList = [
        'Duik',
        'Duik Angela',
        'Duik Bassel',
        'Duik Bassel.1',
        'Duik Bassel.2',
        'DuGR',
        'DuIO',
        'DuSI',
        'DuFlatnr',
        'DuSan'
    ];
    
    var dataList = [
        'RxLab',
        'RxLaboratory',
        'DuAEF',
        'DuESF'
    ];

    var dataFolders = [
        Folder.appData,
        Folder.temp,
        Folder.userData
    ];

    var userFolders = [
        Folder.desktop,
        Folder.myDocuments
    ];

    function wipeFolder(folder) {
        try {
        folder = getFolder(folder);
        if ( !folder ) return false;

        //get content and remove 
        var files = folder.getFiles();
        for (var i = files.length - 1; i >= 0; i--)
        {
            var file = files[i];
            if ( file instanceof Folder ) wipeFolder(file);
            else file.remove();
        };
        folder.remove();
        }catch(e) {alert(e);}
    }

    function getDataFolders(folder) {
        folder = getFolder(folder);
        if (!folder) return [];

        var folders = [];

        var subfolders = folder.getFiles(isFolder);
        for (var i = 0; i < subfolders.length; i++) {
            var f = subfolders[i];
            if (f.name == 'DuESF') folders.push(f);
            else if (f.name == 'DuAEF') folders.push(f);
            else if (f.name == 'AdobeScripts') folders.push(f);
            else folders = folders.concat( getDataFolders(f) );
        }

        return folders;
    }

    function scanForDataFolders() {
        var folders = [];

        for (var i = 0; i < dataFolders.length; i++) {
            var folder = dataFolders[i];
            if (! (folder instanceof Folder) ) continue;
            var uri = folder.fsName;
            for (var j = 0; j < dataList.length; j++) {
                progress('Scanning for data in:', uri);
                folders = folders.concat( getDataFolders( uri + '/' + dataList[j] ) );
            }
        }
              
        return folders;
    }

    function isSettingsFile(file, scriptName) {
        var n = file.name;

        // keep libraries
        if ( n.indexOf('script_library') >= 0 ) return false;
        if ( n.indexOf('animation_library') >= 0 ) return false;
        // must be a json file
        if ( n.indexOf('.json') != n.length - 5 ) return false;
        // must start with the given name
        if ( n.indexOf(scriptName) != 0 ) return false;

        return true;
    }

    function getSettingsFiles(folder) {
        folder = getFolder(folder);
        if (!folder) return [];

        var files = [];

        var subfolders = folder.getFiles();
        for (var i = 0; i < subfolders.length; i++) {
            var f = subfolders[i];
            if (isFile(f)) {
                for (var j = 0; j < scriptList.length; j++)
                    if (isSettingsFile(f, scriptList[j])) {
                        files.push(f);
                        break;
                    }
            } else {
                files = files.concat( getSettingsFiles(f) );
            }
        }

        return files;
    }

    function scanForSettingsFiles() {
        var files = [];

        var fs = dataFolders.concat(userFolders);
        
        for(var i = 0; i < fs.length; i++) {
            var folder = fs[i];
            if (! (folder instanceof Folder) ) continue;
            var uri = folder.fsName;
            for (var j = 0; j < dataList.length; j++) {
                progress('Scanning for files in:', uri);
                files = files.concat( getSettingsFiles( uri + '/' + dataList[j] ) );
            }
            for (var j = 0; j < scriptList.length; j++) {
                progress('Scanning for files in:', uri);
                files = files.concat( getSettingsFiles( uri + '/' + scriptList[j] ) );
            }
        }
        return files;
    }

    // Prep progressbar
    var nDataF = dataFolders.length;
    var nDataL =  dataList.length;
    var nUserF = userFolders.length;
    var nScriptL = scriptList.length;
    progressMax(nDataF * nDataL);

    // Wipe all folders which may contain DuESF/RxLab Data,
    // And remove all settings and language files
    var foldersToWipe = scanForDataFolders();

    if (foldersToWipe.length == 0) {
        alert("No data folder found to wipe. Continuing with settings files...");
    }
    else if (confirm("We're going to wipe these folders:\n\n" + foldersToWipe.join('\n') + '\n\nDo you want to continue?') ) {
        progressReset();
        progressMax(foldersToWipe.length);
        for (var i = 0; i < foldersToWipe.length; i++ ) {
            progress('Wiping:', foldersToWipe[i].fsName);
            wipeFolder(foldersToWipe[i]);
        }
    }

    progressMax((nDataF + nUserF) * (nDataL + nScriptL));

    var settingsToRemove = scanForSettingsFiles();    

    if (foldersToWipe.length == 0) {
        alert("No settings found.");
    } 
    else if (confirm("We're going to remove these files:\n\n" + settingsToRemove.join('\n') + '\n\nDo you want to continue?') ) {
        for (var i = 0; i < settingsToRemove.length; i++ ){
            progressReset();
            progressMax(settingsToRemove.length);
            progress('Removing:', settingsToRemove[i].fsName);
            settingsToRemove[i].remove();
        }
    }
    alert("Done!");

    progressReset();

}

// UI

function progress(text, secText) {
    progressBar.value = progressBar.value + 1;
    statusLabel.text = text;
    statusSecLabel.text = secText;
    //win.window.update();
    updateUI();
}

function progressMax(max) {
    progressBar.maxValue = max;
    //win.window.update();
    updateUI();
}

function progressReset() {
    progressBar.value = 0;
    statusLabel.text = 'Current Status:';
    statusSecLabel.text = 'Ready to help!';
    //win.window.update();
    updateUI();
}

function updateUI() {
    win.layout.layout( true );
    win.layout.resize();
}

var win;
if (thisObj instanceof Panel) win = thisObj;
else win = new Window( 'palette', "DuSI", undefined,
{
    resizeable: true,
    borderless: false
} );

win.orientation = 'column';
win.alignChildren = ['fill', 'top'];

var sysInfoButton = win.add('button', undefined, "Get System Information");
sysInfoButton.onClick = function () { try { getSysInfo(); } catch(e) { alert(e); } };

var cleanButton = win.add('button', undefined, "Fix / Uninstall all Duduf and RxLab. Scripts" );
cleanButton.onClick = wipeScripts;

var progressBar = win.add('progressbar', undefined);
progressBar.alignment = ['fill', 'bottom'];
progressBar.maximumSize = [32000, 10];

var statusGroup = win.add('group');
statusGroup.orientation = 'row';
statusGroup.alignment = ['fill', 'bottom'];
statusGroup.margins = 0;

var statusLabelGroup = statusGroup.add('group');
statusLabelGroup.spacing = 3;
statusLabelGroup.margins = 0;
statusLabelGroup.orientation = 'column';
statusLabelGroup.alignment = ['fill', 'center'];
statusLabelGroup.alignChildren = ['fill', 'fill'];

var statusLabel = statusLabelGroup.add('statictext');

var statusSecLabel = statusLabelGroup.add('statictext');

var versionLabel = statusGroup.add( 'button', undefined, 'v' + scriptVersion );
versionLabel.alignment = ['right', 'fill'];
versionLabel.onClick = function() { openURL('https://rxlaboratory.org/tools/dusi') };

// SHOW

progressReset();

win.onResizing = win.onResize = function()
{
    try
    {
        win.layout.resize();
    }
    catch ( e )
    {}
}

// If it's a Window, it needs to be shown
if ( win instanceof Window )
{
    //ui.center();
    win.show();
}

})(this);