var logging = require("./logging");
var config = require("./config");
var crc = require("crc").crc32;

var human_status = {
  "-2": "user error",
  "-1": "server error",
  0: "none",
  1: "cached",
  2: "downloaded",
  3: "checked",
};


// handles HTTP responses
// +request+ a http.IncomingMessage
// +response+ a http.ServerResponse
// +result+ an object with:
//  * status:   see human_status, required
//  * redirect: redirect URL
//  * body:     file or message, required unless redirect is present or status is < 0
//  * type:     a valid Content-Type, required if body is present
//  * hash:     image hash, required when body is an image
//  * err:      a possible Error
module.exports = function(request, response, result) {

  response.on("close", function() {
    logging.warn(request.id, "Connection closed");
  });

  response.on("finish", function() {
    logging.log(request.id, response.statusCode, "(" + human_status[result.status] + ")");
  });

  response.on("error", function(err) {
    logging.error(request.id, err);
  });

  // These headers are the same for every response
  var headers = {
    "Content-Type": result.type || "text/plain",
    "Cache-Control": "max-age=" + config.browser_cache_time + ", public",
    "Response-Time": Date.now() - request.start,
    "X-Storage-Type": human_status[result.status],
    "X-Request-ID": request.id,
    "Access-Control-Allow-Origin": "*"
  };

  if (result.err) {
    logging.error(result.err);
  }

  if (result.body) {
    // use Mojang's image hash if available
    // use crc32 as a hash function otherwise
    var etag = result.body && result.hash && result.hash.substr(0, 10) || crc(result.body);
    headers.Etag = "\"" + etag + "\"";

    // handle etag caching
    var incoming_etag = request.headers["if-none-match"];
    if (incoming_etag && incoming_etag === headers.Etag) {
      logging.debug("Etag matches");
      response.writeHead(304, headers);
      response.end();
      return;
    }
  }

  if (result.redirect) {
    headers.Location = result.redirect;
    response.writeHead(307, headers);
    response.end();
    return;
  }

  if (result.status === -2) {
    response.writeHead(422, headers);
    response.end(result.body);
  } else if (result.status === -1) {
    response.writeHead(500, headers);
    response.end(result.body);
  } else {
    response.writeHead(200, headers);
    response.end(result.body);
  }
};
var logging = require("./logging");
var config = require("./config");
var crc = require("crc").crc32;

var human_status = {
  "-2": "user error",
  "-1": "server error",
  0: "none",
  1: "cached",
  2: "downloaded",
  3: "checked",
};


// handles HTTP responses
// +request+ a http.IncomingMessage
// +response+ a http.ServerResponse
// +result+ an object with:
//  * status:   see human_status, required
//  * redirect: redirect URL
//  * body:     file or message, required unless redirect is present or status is < 0
//  * type:     a valid Content-Type for the body, defaults to "text/plain"
//  * hash:     image hash, required when body is an image
//  * err:      a possible Error
module.exports = function(request, response, result) {

  response.on("close", function() {
    logging.warn(request.id, "Connection closed");
  });

  response.on("finish", function() {
    logging.log(request.id, response.statusCode, "(" + human_status[result.status] + ")");
  });

  response.on("error", function(err) {
    logging.error(request.id, err);
  });

  // These headers are the same for every response
  var headers = {
    "Content-Type": result.type || "text/plain",
    "Cache-Control": "max-age=" + config.browser_cache_time + ", public",
    "Response-Time": Date.now() - request.start,
    "X-Storage-Type": human_status[result.status],
    "X-Request-ID": request.id,
    "Access-Control-Allow-Origin": "*"
  };

  if (result.err) {
    logging.error(result.err);
  }

  if (result.body) {
    // use Mojang's image hash if available
    // use crc32 as a hash function otherwise
    var etag = result.body && result.hash && result.hash.substr(0, 10) || crc(result.body);
    headers.Etag = "\"" + etag + "\"";

    // handle etag caching
    var incoming_etag = request.headers["if-none-match"];
    if (incoming_etag && incoming_etag === headers.Etag) {
      logging.debug("Etag matches");
      response.writeHead(304, headers);
      response.end();
      return;
    }
  }

  if (result.redirect) {
    headers.Location = result.redirect;
    response.writeHead(307, headers);
    response.end();
    return;
  }

  if (result.status === -2) {
    response.writeHead(422, headers);
    response.end(result.body);
  } else if (result.status === -1) {
    response.writeHead(500, headers);
    response.end(result.body);
  } else {
    response.writeHead(200, headers);
    response.end(result.body);
  }
};
correct comment about result.type