/**
 * @file Ship App
 * @author treelite(c.xinle@gmail.com)
 */

'use strict';

import fs from 'fs';
import express from 'express';
import extend from 'xtend';
import logger from './lib/logger';
import exists from './lib/util/exists';
import pipe from './lib/pipe';
import Meta from './lib/meta';
import lock from './lib/lock';

let options = {
    port: 80,
    log: '/var/log/ship',
    meta: '/etc/ship/ship.json'
};

let file = process.argv[2];
if (file && exists(file)) {
    file = fs.readFileSync(file, 'utf8');
    let config = JSON.parse(file);
    options = extend(options, config);
}

let log = logger(options.log);

let meta = new Meta(options.meta);
meta.on('error', error => log.error('[meta] %s', error));

let app = express();

// FIXME
// 规范错误处理
app.post('/:repository/:event', (req, res) => {
    let {repository, event} = req.params;
    let action = meta.get(repository, event);

    if (!action) {
        return res.status(404).end();
    }

    if (!lock(`${repository}-${event}`)) {
        return res.status(403).end();
    }

    let data;
    try {
        data = JSON.parse(decodeURIComponent(req.body));
    }
    catch (e) {
        return res.status(400);
    }

    pipe(action, data)
        .then(
            info => log.info('[pipe] %s', JSON.stringify(info), req.params),
            error => log.error('[pipe] %s', error, req.params)
        );

    res.status(200).end();
});

app.listen(options.port);

log.info('server start');

@@ -106,29 +106,23 @@
 ort 
-express from 'express
+path from 'path
 ';%0Ai
@@ -159,76 +159,71 @@
 ort 
-logger from './lib/logger';%0Aimport exists from './lib/util/exists
+express from 'express';%0Aimport bodyParser from 'body-parser
 ';%0A
+%0A
 impo
@@ -291,16 +291,18 @@
 ort lock
+er
  from '.
@@ -310,16 +310,93 @@
 lib/lock
+er';%0Aimport logger from './lib/logger';%0Aimport exists from './lib/util/exists
 ';%0A%0Alet 
@@ -543,23 +543,40 @@
 ) %7B%0A    
-file = 
+let config = JSON.parse(
 fs.readF
@@ -596,16 +596,17 @@
  'utf8')
+)
 ;%0A    le
@@ -611,34 +611,196 @@
 let 
-config = JSON.parse(file);
+dir = path.dirname(file);%0A    if (config.log) %7B%0A        config.log = path.resolve(dir, config.log);%0A    %7D%0A    if (config.meta) %7B%0A        config.meta = path.resolve(dir, config.meta);%0A    %7D
 %0A   
@@ -946,14 +946,13 @@
 or('
-%5B
 meta
-%5D
+:
  %25s'
@@ -971,22 +971,379 @@
 let 
-app = express(
+lock = locker();%0A%0Alet app = express();%0A%0A// %E8%AE%BF%E9%97%AE%E6%97%A5%E5%BF%97%0Aapp.use((req, res, next) =%3E %7B%0A    res.on('finish', () =%3E %7B%0A        if (res.statusCode %3E= 500) %7B%0A            log.error('access: %25d %25s', res.statusCode, req.url);%0A        %7D%0A        else %7B%0A            log.info('access: %25d %25s', res.statusCode, req.url);%0A        %7D%0A    %7D);%0A    next();%0A%7D);%0A%0Aapp.use(bodyParser.text(%7Btype: '*/*'%7D)
 );%0A%0A
@@ -1783,16 +1783,22 @@
 tus(400)
+.end()
 ;%0A    %7D%0A
@@ -1794,24 +1794,104 @@
 d();%0A    %7D%0A%0A
+    log.info('pipe receive', extend(%7Bdata: JSON.stringify(data)%7D, req.params));%0A
     pipe(act
@@ -1946,22 +1946,29 @@
 g.info('
-%5B
 pipe
-%5D
+ success:
  %25s', JS
@@ -2036,14 +2036,18 @@
 or('
-%5B
 pipe
-%5D
+ fail:
  %25s'
@@ -2107,24 +2107,233 @@
 end();%0A%7D);%0A%0A
+app.use((error, req, res, next) =%3E %7B%0A    log.error('unkown error: %25s %25s', error.message, req.url, %7Bstack: error.stack%7D);%0A    res.status(500).end();%0A%7D);%0A%0Aapp.use((req, res) =%3E %7B%0A    res.status(404).end();%0A%7D);%0A%0A
 app.listen(o
@@ -2369,12 +2369,32 @@
 er start
-'
+ at %25d', options.port
 );%0A

Update logic