/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
const autoprefixer = require('autoprefixer');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const path = require('path');
const fs = require('fs');
const PropertiesReader = require('properties-reader');
const LessToJs = require('less-vars-to-js');
const pkg = require('./../../package.json');
const webpack = require('webpack');
const pj = path.join;

const ENV = process.env.NODE_ENV || 'development';
const ROOT_DIR = pj(path.resolve(__dirname), './../..');
const SRC_DIR = pj(ROOT_DIR, 'app');
const DEST_DIR = pj(ROOT_DIR, 'dist');
const NODE_MODULES_DIR = pj(ROOT_DIR, 'node_modules');
const UTILS_NODE_MODULES_DIR = pj(ROOT_DIR, '../utils/node_modules');
const BRAND_FALLBACK_DIR = pj(ROOT_DIR, '../branding');
const BRAND_DIR = (process.env.BROOKLYN_UI_BRAND_DIR && process.env.BROOKLYN_UI_BRAND_DIR!='default')
    // default accepted because mvn needs to pass a value and empty isn't allowed
    ? path.isAbsolute(process.env.BROOKLYN_UI_BRAND_DIR) 
      ? process.env.BROOKLYN_UI_BRAND_DIR 
      : pj(ROOT_DIR, process.env.BROOKLYN_UI_BRAND_DIR) 
    : pj(BRAND_FALLBACK_DIR, 'brooklyn');

const brandProps = PropertiesReader(path.resolve(BRAND_FALLBACK_DIR, 'brand.properties'));
brandProps.append(path.resolve(BRAND_DIR, 'brand.properties'));
const BRAND_IDENTIFIER = brandProps.get('brand-identifier');
if (!BRAND_IDENTIFIER) {
    throw("The brand.properties file in "+BRAND_DIR+" must specify a brand-identifier.");
}
var brandLess = {};
const getBrandedText = ((brandProps) => (key) => {
    var branded = key.split('.').reduce(function(o, x) {
        return o ? o[x] : undefined;
    }, brandProps);

    // TODO we should remove the "brooklyn" sections in package.json as a way of branding; 
    // always use the props above
    return branded ? branded : key.split('.').reduce(function(o, x) {
        return o ? o[x] : undefined;
    }, pkg.brooklyn);
});

const getStyleLoader = function() {
    var loader = [];
    loader.push('css' + (ENV === 'development' ? '?sourceMap' : ''));
    loader.push('postcss');

    const brandLessVars = LessToJs(fs.readFileSync(path.resolve(BRAND_DIR, 'brand.less'), 'utf8'));
    const brandLessVarsFromFallback = LessToJs(fs.readFileSync(path.resolve(BRAND_FALLBACK_DIR, 'brand.less'), 'utf8'));
    var brandLessVarsFromProps = brandProps.getByRoot('less');
    Object.assign(brandLess, brandLessVarsFromFallback, brandLessVarsFromProps, brandLessVars);
    brandLess['brand-identifier'] = BRAND_IDENTIFIER;

    var lessConfig = { modifyVars: brandLess };
    
    if (ENV === 'development') {
        lessConfig.sourceMap = true;
    }
    loader.push('less?' + JSON.stringify(lessConfig));

    return loader.join('!');
};

console.log('Build with:', 'ENV', ENV, '-', 'brand-identifier', BRAND_IDENTIFIER);

const config = {
    context: SRC_DIR,
    entry: {
        index: [
            'babel-polyfill',
            'index.less',
            'index.js'
        ]
    },
    output: {
        filename: '[name].[hash].js',
        path: DEST_DIR
    },
    module: {
        loaders: [{
            test: /\.js$/i,
            exclude: /node_modules/,
            loader: 'babel',
            query: { 
              presets: [
                'babel-preset-env',
                'babel-preset-stage-0',
              ].map(require.resolve) 
            }
        }, {
            test: /\.less$/,
            exclude: /index.less/,
            loader: getStyleLoader()
        }, {
            test: /index.less$/,
            loader: ExtractTextPlugin.extract(getStyleLoader())
        }, {
            test: /\.(jpe?g|png|gif)$/i,
            loaders: [
                'url-loader?limit=50000&name=assets/[name].[hash].[ext]',
                'image-webpack'
            ]
        }, {
            test: /\.(woff|svg|ttf|eot)([\?]?.*)$/,
            loader: 'file-loader?name=assets/[name].[hash].[ext]'
        }, {
            test: /\.json$/,
            loader: 'raw-loader'
        }, {
            test: /\.html$/,
            loader: 'html?interpolate&-minimize&attrs[]=img:src&attrs[]=img:data-src&attrs[]=object:data'
        }]
    },
    resolve: {
        alias: {
            'brooklyn-shared': path.resolve(ROOT_DIR, '../shared'),
            // user-supplied brand dir for overwrites (defaults to brooklyn brand)
            'brand': BRAND_DIR,
            // fallback branding info
            'brand-fallback': BRAND_FALLBACK_DIR,
            // brand-supplied JS definitions
            'brand-js': fs.existsSync(pj(BRAND_DIR, 'brand.js')) ? pj(BRAND_DIR, 'brand.js') : pj(BRAND_FALLBACK_DIR, 'brand.js'),
        },
        root: SRC_DIR,
        extensions: ['', '.js'],
        modulesDirectories: [
            NODE_MODULES_DIR,
            UTILS_NODE_MODULES_DIR
        ]
    },
    resolveLoader: {
        root: [NODE_MODULES_DIR],
        modulesDirectories: [
            NODE_MODULES_DIR,
            UTILS_NODE_MODULES_DIR
        ]
    },
    postcss: [
        autoprefixer({
            browsers: ['last 2 versions']
        })
    ],
    ejsHtml: {
        // a "brooklyn" section in package.json can contain extra info like `product.name` and `appname`
        app: pkg.brooklyn,
        brand: brandProps.path(),
        getBrandedText: getBrandedText(brandProps.path())
    },
    plugins: [
        new ExtractTextPlugin('[name].[chunkhash].css'),
        new webpack.optimize.OccurenceOrderPlugin(),
        new webpack.DefinePlugin({
            __BROOKLYN_VERSION__: JSON.stringify(process.env.BROOKLYN_VERSION || '1.1.0-SNAPSHOT'),
            __BUILD_NAME__: JSON.stringify(process.env.BUILD_NAME),
            __BUILD_VERSION__: JSON.stringify(process.env.BUILD_VERSION),
            __BUILD_BRANCH__: JSON.stringify(process.env.BUILD_BRANCH),
            __BUILD_COMMIT_ID__: JSON.stringify(process.env.BUILD_COMMIT_ID),
            // from bootstrap, possibly overridden, included here for access from JS
            __BRAND_SUCCESS__: JSON.stringify(brandLess['@brand-success'] || '#5cb85c'),
            __BRAND_DANGER__: JSON.stringify(brandLess['@brand-danger'] || '#d9534f'),
            'process.env.NODE_ENV': JSON.stringify(ENV),
            // used by brBrandInfo.getBrandedText
            __BRAND_PROPS__: JSON.stringify(brandProps.path()),
        }),
        new webpack.ProvidePlugin({
            'Promise': 'imports?this=>global!exports?global.Promise!es6-promise'
        }),
        new HtmlWebpackPlugin({
            template: 'ejs-html!' + pj(SRC_DIR, 'index.html'),
            chunksSortMode: 'dependency'
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor',
            minChunks: function (module) {
                // This prevents stylesheet resources with the .css or .scss extension
                // from being moved from their original chunk to the vendor chunk
                if (module.resource && (/^.*\.(css|scss|less)$/).test(module.resource)) {
                    return false;
                }
                return module.context && module.context.indexOf('node_modules') !== -1;
            }
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: 'manifest',
            minChunks: Infinity
        })
    ]
};

if (fs.existsSync(pj(BRAND_DIR, 'build-config-tweak.js'))) {
  eval(""+fs.readFileSync(pj(BRAND_DIR, 'build-config-tweak.js')));
}

if (ENV === 'development') {
    config.watch = true;
    config.debug = true;
    config.devtool = 'source-map';
    config.entry.index.push('webpack-hot-middleware/client');
    config.plugins.push(new webpack.HotModuleReplacementPlugin())
} else {
    config.plugins.push(
        new webpack.optimize.DedupePlugin(),
        new webpack.optimize.UglifyJsPlugin({
            mangle: false,
            compress: {
                dead_code: true,
                unused: true,
                warnings: false
            }
        }),
        new webpack.BannerPlugin(getBrandedText(brandProps.path())("banner"))
    )
}

module.exports = config;
