// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
// VMOptions=
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write

#import("dart:isolate");
#import("dart:io");

class TestServerMain {
  TestServerMain()
      : _statusPort = new ReceivePort(),
        _serverPort = null {
    _serverPort = spawnFunction(startTestServer);
  }

  void setServerStartedHandler(void startedCallback(int port)) {
    _startedCallback = startedCallback;
  }

  void start() {
    // Handle status messages from the server.
    _statusPort.receive((var status, SendPort replyTo) {
      if (status.isStarted) {
        _startedCallback(status.port);
      }
    });

    // Send server start message to the server.
    var command = new TestServerCommand.start();
    _serverPort.send(command, _statusPort.toSendPort());
  }

  void shutdown() {
    // Send server stop message to the server.
    _serverPort.send(new TestServerCommand.stop(), _statusPort.toSendPort());
    _statusPort.close();
  }

  void chunkedEncoding() {
    // Send chunked encoding message to the server.
    _serverPort.send(
        new TestServerCommand.chunkedEncoding(), _statusPort.toSendPort());
  }

  ReceivePort _statusPort;  // Port for receiving messages from the server.
  SendPort _serverPort;  // Port for sending messages to the server.
  var _startedCallback;
}


class TestServerCommand {
  static const START = 0;
  static const STOP = 1;
  static const CHUNKED_ENCODING = 2;

  TestServerCommand.start() : _command = START;
  TestServerCommand.stop() : _command = STOP;
  TestServerCommand.chunkedEncoding() : _command = CHUNKED_ENCODING;

  bool get isStart => _command == START;
  bool get isStop => _command == STOP;
  bool get isChunkedEncoding => _command == CHUNKED_ENCODING;

  int _command;
}


class TestServerStatus {
  static const STARTED = 0;
  static const STOPPED = 1;
  static const ERROR = 2;

  TestServerStatus.started(this._port) : _state = STARTED;
  TestServerStatus.stopped() : _state = STOPPED;
  TestServerStatus.error() : _state = ERROR;

  bool get isStarted => _state == STARTED;
  bool get isStopped => _state == STOPPED;
  bool get isError => _state == ERROR;

  int get port => _port;

  int _state;
  int _port;
}


void startTestServer() {
  var server = new TestServer();
  server.init();
  port.receive(server.dispatch);
}


class TestServer {
  // Return a 404.
  void _notFoundHandler(HttpRequest request, HttpResponse response) {
    response.statusCode = HttpStatus.NOT_FOUND;
    response.headers.set("Content-Type", "text/html; charset=UTF-8");
    response.outputStream.writeString("Page not found");
    response.outputStream.close();
  }

  // Check the "Host" header.
  void _hostHandler(HttpRequest request, HttpResponse response) {
    Expect.equals(1, request.headers["Host"].length);
    Expect.equals("www.dartlang.org:1234", request.headers["Host"][0]);
    Expect.equals("www.dartlang.org", request.headers.host);
    Expect.equals(1234, request.headers.port);
    response.statusCode = HttpStatus.OK;
    response.outputStream.close();
  }

  // Set the "Expires" header using the expires property.
  void _expires1Handler(HttpRequest request, HttpResponse response) {
    Date date = new Date.utc(1999, Date.JUN, 11, 18, 46, 53, 0);
    response.headers.expires = date;
    Expect.equals(date, response.headers.expires);
    response.outputStream.close();
  }

  // Set the "Expires" header.
  void _expires2Handler(HttpRequest request, HttpResponse response) {
    response.headers.set("Expires", "Fri, 11 Jun 1999 18:46:53 GMT");
    Date date = new Date.utc(1999, Date.JUN, 11, 18, 46, 53, 0);
    Expect.equals(date, response.headers.expires);
    response.outputStream.close();
  }

  void _contentType1Handler(HttpRequest request, HttpResponse response) {
    Expect.equals("text/html", request.headers.contentType.value);
    Expect.equals("text", request.headers.contentType.primaryType);
    Expect.equals("html", request.headers.contentType.subType);
    Expect.equals("utf-8", request.headers.contentType.parameters["charset"]);

    ContentType contentType = new ContentType("text", "html");
    contentType.parameters["charset"] = "utf-8";
    response.headers.contentType = contentType;
    response.outputStream.close();
  }

  void _contentType2Handler(HttpRequest request, HttpResponse response) {
    Expect.equals("text/html", request.headers.contentType.value);
    Expect.equals("text", request.headers.contentType.primaryType);
    Expect.equals("html", request.headers.contentType.subType);
    Expect.equals("utf-8", request.headers.contentType.parameters["charset"]);

    response.headers.set(HttpHeaders.CONTENT_TYPE,
                         "text/html;  charset = utf-8");
    response.outputStream.close();
  }

  void _cookie1Handler(HttpRequest request, HttpResponse response) {
    // No cookies passed with this request.
    Expect.equals(0, request.cookies.length);

    Cookie cookie1 = new Cookie("name1", "value1");
    Date date = new Date.utc(2014, Date.JAN, 5, 23, 59, 59, 0);
    cookie1.expires = date;
    cookie1.domain = "www.example.com";
    cookie1.httpOnly = true;
    response.cookies.add(cookie1);
    Cookie cookie2 = new Cookie("name2", "value2");
    cookie2.maxAge = 100;
    cookie2.domain = ".example.com";
    cookie2.path = "/shop";
    response.cookies.add(cookie2);
    response.outputStream.close();
  }

  void _cookie2Handler(HttpRequest request, HttpResponse response) {
    // Two cookies passed with this request.
    Expect.equals(2, request.cookies.length);
    response.outputStream.close();
  }

  void _flushHandler(HttpRequest request, HttpResponse response) {
    response.outputStream.flush();
    response.outputStream.close();
  }

  void init() {
    // Setup request handlers.
    _requestHandlers = new Map();
    _requestHandlers["/host"] =
        (HttpRequest request, HttpResponse response) {
          _hostHandler(request, response);
        };
    _requestHandlers["/expires1"] =
        (HttpRequest request, HttpResponse response) {
          _expires1Handler(request, response);
        };
    _requestHandlers["/expires2"] =
        (HttpRequest request, HttpResponse response) {
          _expires2Handler(request, response);
        };
    _requestHandlers["/contenttype1"] =
        (HttpRequest request, HttpResponse response) {
          _contentType1Handler(request, response);
        };
    _requestHandlers["/contenttype2"] =
        (HttpRequest request, HttpResponse response) {
          _contentType2Handler(request, response);
        };
    _requestHandlers["/cookie1"] =
        (HttpRequest request, HttpResponse response) {
          _cookie1Handler(request, response);
        };
    _requestHandlers["/cookie2"] =
        (HttpRequest request, HttpResponse response) {
          _cookie2Handler(request, response);
        };
    _requestHandlers["/flush"] =
        (HttpRequest request, HttpResponse response) {
          _flushHandler(request, response);
        };
  }

  void dispatch(message, replyTo) {
    if (message.isStart) {
      _server = new HttpServer();
      try {
        _server.listen("127.0.0.1", 0);
        _server.defaultRequestHandler = (HttpRequest req, HttpResponse rsp) {
          _requestReceivedHandler(req, rsp);
        };
        replyTo.send(new TestServerStatus.started(_server.port), null);
      } catch (e) {
        replyTo.send(new TestServerStatus.error(), null);
      }
    } else if (message.isStop) {
      _server.close();
      port.close();
      replyTo.send(new TestServerStatus.stopped(), null);
    } else if (message.isChunkedEncoding) {
      _chunkedEncoding = true;
    }
  }

  void _requestReceivedHandler(HttpRequest request, HttpResponse response) {
    var requestHandler =_requestHandlers[request.path];
    if (requestHandler != null) {
      requestHandler(request, response);
    } else {
      _notFoundHandler(request, response);
    }
  }

  HttpServer _server;  // HTTP server instance.
  Map _requestHandlers;
  bool _chunkedEncoding = false;
}

void testHost() {
  TestServerMain testServerMain = new TestServerMain();
  testServerMain.setServerStartedHandler((int port) {
    HttpClient httpClient = new HttpClient();
    HttpClientConnection conn =
        httpClient.get("127.0.0.1", port, "/host");
    conn.onRequest = (HttpClientRequest request) {
      Expect.equals("127.0.0.1:$port", request.headers["host"][0]);
      request.headers.host = "www.dartlang.com";
      Expect.equals("www.dartlang.com:$port", request.headers["host"][0]);
      Expect.equals("www.dartlang.com", request.headers.host);
      Expect.equals(port, request.headers.port);
      request.headers.port = 1234;
      Expect.equals("www.dartlang.com:1234", request.headers["host"][0]);
      Expect.equals(1234, request.headers.port);
      request.headers.port = HttpClient.DEFAULT_HTTP_PORT;
      Expect.equals(HttpClient.DEFAULT_HTTP_PORT, request.headers.port);
      Expect.equals("www.dartlang.com", request.headers["host"][0]);
      request.headers.set("Host", "www.dartlang.org");
      Expect.equals("www.dartlang.org", request.headers.host);
      Expect.equals(HttpClient.DEFAULT_HTTP_PORT, request.headers.port);
      request.headers.set("Host", "www.dartlang.org:");
      Expect.equals("www.dartlang.org", request.headers.host);
      Expect.equals(HttpClient.DEFAULT_HTTP_PORT, request.headers.port);
      request.headers.set("Host", "www.dartlang.org:1234");
      Expect.equals("www.dartlang.org", request.headers.host);
      Expect.equals(1234, request.headers.port);
      request.outputStream.close();
    };
    conn.onResponse = (HttpClientResponse response) {
      Expect.equals(HttpStatus.OK, response.statusCode);
      httpClient.shutdown();
      testServerMain.shutdown();
    };
  });
  testServerMain.start();
}

void testExpires() {
  TestServerMain testServerMain = new TestServerMain();
  testServerMain.setServerStartedHandler((int port) {
    int responses = 0;
    HttpClient httpClient = new HttpClient();

    void processResponse(HttpClientResponse response) {
      Expect.equals(HttpStatus.OK, response.statusCode);
      Expect.equals("Fri, 11 Jun 1999 18:46:53 GMT",
                    response.headers["expires"][0]);
      Expect.equals(new Date.utc(1999, Date.JUN, 11, 18, 46, 53, 0),
                    response.headers.expires);
      responses++;
      if (responses == 2) {
        httpClient.shutdown();
        testServerMain.shutdown();
      }
    }

    HttpClientConnection conn1 = httpClient.get("127.0.0.1", port, "/expires1");
    conn1.onResponse = (HttpClientResponse response) {
      processResponse(response);
    };
    HttpClientConnection conn2 = httpClient.get("127.0.0.1", port, "/expires2");
    conn2.onResponse = (HttpClientResponse response) {
      processResponse(response);
    };
  });
  testServerMain.start();
}

void testContentType() {
  TestServerMain testServerMain = new TestServerMain();
  testServerMain.setServerStartedHandler((int port) {
    int responses = 0;
    HttpClient httpClient = new HttpClient();

    void processResponse(HttpClientResponse response) {
      Expect.equals(HttpStatus.OK, response.statusCode);
      Expect.equals("text/html; charset=utf-8",
                    response.headers.contentType.toString());
      Expect.equals("text/html", response.headers.contentType.value);
      Expect.equals("text", response.headers.contentType.primaryType);
      Expect.equals("html", response.headers.contentType.subType);
      Expect.equals("utf-8",
                    response.headers.contentType.parameters["charset"]);
      responses++;
      if (responses == 2) {
        httpClient.shutdown();
        testServerMain.shutdown();
      }
    }

    HttpClientConnection conn1 =
        httpClient.get("127.0.0.1", port, "/contenttype1");
    conn1.onRequest = (HttpClientRequest request) {
      ContentType contentType = new ContentType();
      contentType.value = "text/html";
      contentType.parameters["charset"] = "utf-8";
      request.headers.contentType = contentType;
      request.outputStream.close();
    };
    conn1.onResponse = (HttpClientResponse response) {
      processResponse(response);
    };
    HttpClientConnection conn2 =
        httpClient.get("127.0.0.1", port, "/contenttype2");
    conn2.onRequest = (HttpClientRequest request) {
      request.headers.set(HttpHeaders.CONTENT_TYPE,
                          "text/html;  charset = utf-8");
      request.outputStream.close();
    };
    conn2.onResponse = (HttpClientResponse response) {
      processResponse(response);
    };
  });
  testServerMain.start();
}

void testCookies() {
  TestServerMain testServerMain = new TestServerMain();
  testServerMain.setServerStartedHandler((int port) {
    int responses = 0;
    HttpClient httpClient = new HttpClient();

    HttpClientConnection conn1 =
        httpClient.get("127.0.0.1", port, "/cookie1");
    conn1.onResponse = (HttpClientResponse response) {
      Expect.equals(2, response.cookies.length);
      response.cookies.forEach((cookie) {
        if (cookie.name == "name1") {
          Expect.equals("value1", cookie.value);
          Date date = new Date.utc(2014, Date.JAN, 5, 23, 59, 59, 0);
          Expect.equals(date, cookie.expires);
          Expect.equals("www.example.com", cookie.domain);
          Expect.isTrue(cookie.httpOnly);
        } else if (cookie.name == "name2") {
          Expect.equals("value2", cookie.value);
          Expect.equals(100, cookie.maxAge);
          Expect.equals(".example.com", cookie.domain);
          Expect.equals("/shop", cookie.path);
        } else {
          Expect.fail("Unexpected cookie");
        }
      });
      HttpClientConnection conn2 =
          httpClient.get("127.0.0.1", port, "/cookie2");
      conn2.onRequest = (HttpClientRequest request) {
        request.cookies.add(response.cookies[0]);
        request.cookies.add(response.cookies[1]);
        request.outputStream.close();
      };
      conn2.onResponse = (HttpClientResponse ignored) {
        httpClient.shutdown();
        testServerMain.shutdown();
      };
    };
  });
  testServerMain.start();
}

void testFlush() {
  TestServerMain testServerMain = new TestServerMain();
  testServerMain.setServerStartedHandler((int port) {
    HttpClient httpClient = new HttpClient();

    HttpClientConnection conn = httpClient.get("127.0.0.1", port, "/flush");
    conn.onRequest = (HttpClientRequest request) {
      request.outputStream.flush();
      request.outputStream.close();
    };
    conn.onResponse = (HttpClientResponse response) {
      Expect.equals(HttpStatus.OK, response.statusCode);
      httpClient.shutdown();
      testServerMain.shutdown();
    };
  });
  testServerMain.start();
}

void main() {
  testHost();
  testExpires();
  testContentType();
  testCookies();
  testFlush();
}
