/* globals require, __dirname, process */
/*eslint no-console: ["error", { allow: ["log", "info", "warn", "error"] }]*/

const fse = require('fs-extra')
const path = require('path')
const packager = require('electron-packager')
const rebuild = require('electron-rebuild')

// Arguments
//----------------------
let folder = null

if (process.argv.length < 3) {
    console.error('Missing command line parameter "folder"!')
    process.exit(1)
} else {
    folder = process.argv[2]
}

// Settings
//----------------------
let settings = null
const root = path.join(__dirname, '../')

try {
    settings = require(`../${folder}/settings.json`)
} catch (e) {
    console.error('Cannot read settings.json in folder, does it exist?')
    process.exit(1)
}

// Read settings
//----------------------
const title = `--- Build "${settings.name || settings.id}" ---`
const line = Array(title.length + 1).join('-')
console.info(line)
console.info(title)
console.info(line)

// Using folder
//----------------------
const tempFolder = path.join(root, 'temp', settings.id)
console.log(`Using folder ${tempFolder}`)

// Delete temp folder (when last run aborted)
fse.removeSync(tempFolder)
console.log(`Folder ${tempFolder} deleted`)

// Create folder
fse.ensureDirSync(tempFolder)
console.log(`Folder ${tempFolder} created`)

// Create subfolders
const defaultFolders = ['assets', 'browser', 'css', 'lib', 'node_modules', 'server']
console.log(`The folders ${defaultFolders.join(', ')} are included by default`)
const folders = new Set(settings.browser.folders.concat(defaultFolders))
for (let folder of folders) {
    console.log(`Copy folder ${folder}`)
    const folderOld = path.join(root, folder)
    const folderNew = path.join(root, 'temp', settings.id, folder)

    fse.copySync(folderOld, folderNew)
}

// Write package.json
//----------------------
let json = {
    name: settings.id,
    productName: settings.name || settings.id,
    version: settings.version,
    main: 'browser/main.js',
    dependencies: {}
}

// Read and write dependencies
const packageJson = fse.readJsonSync(path.join(root, 'package.json'))
Object.assign(json.dependencies, packageJson.dependencies)

// Add browser dependencies
if (settings.browser.dependencies) {
    let dependencies = {}
    for (let dependency of settings.browser.dependencies) {
        dependencies[dependency] = '*'
    }
    Object.assign(json.dependencies, dependencies)
}

console.log('Create package.json')
fse.writeJsonSync(path.join(tempFolder, 'package.json'), json, {spaces: 4})

// Write URL to settings.json
//----------------------
console.log('Write URL to browser/settings.json')
fse.writeJsonSync(path.join(tempFolder, 'browser/settings.json'), {url: `../${folder}/index.html`}, {spaces: 4})

// Build with electron-packager
//----------------------
console.log('Start electron-packager')
packager({
    dir: `./temp/${settings.id}`,
    arch: 'x64',
    asar: false,
    overwrite: true,
    out: './dist/electron',
    icon: './assets/icons/icon',
    platform: settings.browser.platform || ['darwin', 'win32'],
    prune: false,
    afterCopy: [(buildPath, electronVersion, platform, arch, callback) => {
        console.log(`Rebuild Node.js modules for ${platform}...`)
        rebuild.rebuild({buildPath, electronVersion, arch})
            .then(() => {
                console.log(`...Node.js modules for ${platform} rebuilded`)
                callback()
            })
            .catch(error => {
                console.error(`Error: ${error}`)
                callback(error)
            });
    }]
})
    .then(appPaths => {
        console.log('electron-packager finished')
    
        // Delete temp folder
        //----------------------
        fse.removeSync(tempFolder)
        console.log(`Folder ${tempFolder} deleted`)

        // Write data folders
        //----------------------
        if (settings.browser.data) {
            console.log('Copy data folders')
            for (let folder of settings.browser.data) {
                for (let appPath of appPaths) {
                    console.log(`Copy folder ${folder} to ${appPath}`)
                    const source = path.join(root, folder)
                    const target = path.join(getResourcesPath(root, appPath), folder)
                    fse.copySync(source, target, {
                        dereference: true,
                        filter: item => {
                            if (settings.browser.dataExtensions && fse.lstatSync(item).isFile() && !settings.browser.dataExtensions.includes(path.extname(item).substring(1).toLowerCase())) {
                                return false
                            } else {
                                return true
                            }
                        }
                    })
                }
            }
        }
    
        // Finished
        //----------------------
        console.info('Finished')
    })
    .catch(error => {
        console.error(error)
    })

function getResourcesPath(root, appPath) {
    
    let resourcesPath = ""
    
    if (/darwin/.test(appPath) || /mas/.test(appPath)) {
        resourcesPath = path.join(root, appPath, `${json.productName}.app/Contents/Resources/app`)
    } else if (/win32/.test(appPath) || /linux/.test(appPath)) {
        resourcesPath = path.join(root, appPath, 'resources/app')
    }
    
    return resourcesPath
}