require 'sugar'

if global.window?
    return

fs = require 'fs'
np = require 'path'
cp = require './coffeepages'
ae = require './appengine'

{watcher,utility} = browserBuild = require 'browser-build'

check = (config) ->
    throw new Error "config.node is required" unless config.node?
    throw new Error "config.source is required" unless config.source?
    if Object.isString config.node
        config.node = {directory:config.node}
    if Object.isString config.source
        config.source = {directory:config.source}
    if config.browser?
        config.browser.output.directory ?= "www/js"
        config.browser.output.webroot ?= "www"
        config.browser.output.test ?= "glass-test"
    if config.appengine?.pages
        config.pages =
            input:
                directory: 'war'
            output:
                directory: 'war/WEB-INF/pages'
    return

build = (config, callback) ->
    utility.buildCoffee config.source.directory, config.node.directory, callback
watchCoffee = (config) ->
    utility.watchCoffee config.source.directory, config.node.directory
    if config.browser?
        browserBuild.watch config.browser

runTest = (config, callback) ->
    list = utility.list config.node.directory, {include:".js"}
    return unless config.browser.output.test?
    testModule = np.join config.browser.output.directory, 'test/test.js'
    utility.spawn "node.cmd #{testModule} #{list.join ' '}", callback

    # if config.browser.output.test is 'mocha'
    #     utility.spawn "mocha.cmd --harmony -R spec #{list.join ' '}", callback
    # else if config.browser.output.test is 'glass-test'
    #     try
    #         utility.spawn "node.cmd node_modules/glass-test/lib/index.js #{list.join ' '}"
    #     catch e
    #         console.log "Couldn't run glass-test: #{e}"
watchTest = (config) ->
    # use a directory watcher to invoke nodeunit tests
    debouncedRunTest = (->
        runTest config
    ).debounce(500)
    options =
        filter: ".js"
        initial: false
    watcher.watchDirectory config.node.directory, options, debouncedRunTest
getPackageJson = (config) ->
    path = 'package.json'
    JSON.parse fs.readFileSync(path, 'utf8')
buildCommon = (config) ->
    check config
    for file in ["README.md", "package.json"]
        if fs.existsSync file
            utility.copy file, "#{config.node.directory}/#{file}"
    # copy package.json and readme.md to node_modules
module.exports = exports =
    # re-export utility and watchers
    utility: utility
    watcher: watcher
    # builds this project
    build: (config, callback) ->
        buildCommon config
        build config, ->
            if config.browser?
                browserBuild.build config.browser
            cp.buildCoffeePages config.pages
            if config.appengine?
                ae.build()
            runTest config, callback

    # watches input and incrementally builds output
    watch: (config) ->
        buildCommon config
        watchCoffee config
        watchTest config
        cp.watchCoffeePages config.pages
        if config.appengine?
            ae.run()
            if config.appengine.java?
                watcher.watchDirectory config.appengine.java, {initial:false}, (file) ->
                    ae.restart()
        # maybe start a web server
        else if config.browser?.port?
            utility.startWebServer
                root: config.browser.output.webroot
                port: config.browser.port
        # server = {ant:'runserver'}
    kill: (config, callback) ->
        if config.appengine?
            ae.kill()
    # runs our unit tests
    test: (config, callback) ->
        check config
        runTest config, callback
    # runs npm publish on the output library
    publish: (config, callback) ->
        exports.build config, ->
            utility.spawn "npm.cmd publish #{config.node.directory}", callback
    # bumps the package.json build version number
    bump: (config, callback) ->
        pj = getPackageJson config
        version = pj.version.split '.'
        # bump the build version
        version[2] = parseInt(version[2]) + 1
        version = version.join '.'
        utility.spawn "npm.cmd version #{version}", callback


