const fs = require('fs')
const path = require('path')
const http = require('http');

const workDir = '.';
const port = 8082;

const mime = {
    css: 'text/css',
    gif: 'image/gif',
    html: 'text/html',
    jpg: 'image/jpeg',
    js: 'application/javascript',
    png: 'image/png',
    svg: 'image/svg+xml',
    txt: 'text/plain',
    xhtml: 'application/xhtml+xml',
    xml: 'text/xml',
    xsd: 'text/xml',
    xsl: 'text/xml'
};

const server = http.createServer(function(request, response) {

  console.log(`${request.method} ${request.url}`);
  console.log(JSON.stringify(request.headers));
  console.log('----');

  let filepath = workDir + request.url.toString().split('?')[0];

  if (request.method.toUpperCase() == 'GET') {
    // Default file is index.html.
    filepath = filepath.replace(/\/$/, '/index.html');
    // Check if path is within the work directory.
    if (filepath.indexOf(workDir + '/') !== 0) {
      response.statusCode = 403;
      response.setHeader('Content-Type', 'text/plain');
      return response.end('Forbidden');
    }
    var type = mime[path.extname(filepath).slice(1)] || 'text/plain';
    var getStream = fs.createReadStream(filepath);
    getStream.on('open', function () {
      console.log(`Data is read from file ${filepath}`);
      response.setHeader('Content-Type', type);
      response.writeHead(200);
      getStream.pipe(response);
    });
    getStream.on('error', function () {
      console.log(`Data can not be read from file ${filepath}`);
      response.setHeader('Content-Type', 'text/plain');
      response.statusCode = 404;
      response.end('Not found');
    });

    /* Old code:
    fs.readFile(filepath, (err, data) => {
      if(err) {
        console.log(JSON.stringify(err.message));
        response.writeHead(404, err.message);
        response.end();
      } else {
        console.log(`Data is read from file ${filepath}`);
        response.writeHead(200);
        response.end(data.toString());
      }
    });
    */
  } else if (request.method.toUpperCase() == 'PUT') {
    let body = '';
    request.on('data', (chunk) => {
      body += chunk;
    });
    request.on('end', () => {
      fs.mkdir(path.dirname(filepath), {recursive: true}, (err) => {
        if (err) {
          response.writeHead(500, `Cannot create directory '${path.dirname(filepath)}' for '${filepath}'.`);
          response.end();
        } else {
          fs.writeFile(filepath, body, (err) => {
            if(err) {
              console.log(JSON.stringify(err.message));
              response.writeHead(500, err.message);
              response.end();
            } else {
              console.log(`Data has been written to file ${filepath}`);
              response.writeHead(200);
              response.end();
            }
          });
        }
      });
    });
  } else {
    response.writeHead(405);
    response.end();
  }

});

server.listen(port);
console.log(`Web server started at port ${port}.`);
