// Copyright (c) 2013, 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.

// @dart = 2.9

import "dart:io";

import "package:expect/expect.dart";

void testCookies() {
  var cookies = [
    {'abc': 'def'},
    {'ABC': 'DEF'},
    {'Abc': 'Def'},
    {'Abc': 'Def', 'SID': 'sffFSDF4FsdfF56765'}
  ];

  HttpServer.bind("127.0.0.1", 0).then((server) {
    server.listen((HttpRequest request) {
      // Collect the cookies in a map.
      var cookiesMap = {};
      request.cookies.forEach((c) => cookiesMap[c.name] = c.value);
      int index = int.parse(request.uri.path.substring(1));
      Expect.mapEquals(cookies[index], cookiesMap);
      // Return the same cookies to the client.
      cookiesMap.forEach((k, v) {
        request.response.cookies.add(new Cookie(k, v));
      });
      request.response.close();
    });

    int count = 0;
    HttpClient client = new HttpClient();
    for (int i = 0; i < cookies.length; i++) {
      client.get("127.0.0.1", server.port, "/$i").then((request) {
        // Send the cookies to the server.
        cookies[i].forEach((k, v) {
          request.cookies.add(new Cookie(k, v));
        });
        return request.close();
      }).then((response) {
        // Expect the same cookies back.
        var cookiesMap = {};
        response.cookies.forEach((c) => cookiesMap[c.name] = c.value);
        Expect.mapEquals(cookies[i], cookiesMap);
        response.cookies.forEach((c) => Expect.isTrue(c.httpOnly));
        response.listen((d) {}, onDone: () {
          if (++count == cookies.length) {
            client.close();
            server.close();
          }
        });
      }).catchError((e, trace) {
        String msg = "Unexpected error $e";
        if (trace != null) msg += "\nStackTrace: $trace";
        Expect.fail(msg);
      });
    }
  });
}

void testValidateCookieWithDoubleQuotes() {
  Expect.equals(Cookie('key', 'value').toString(), 'key=value; HttpOnly');
  Expect.equals(Cookie('key', '').toString(), 'key=; HttpOnly');
  Expect.equals(Cookie('key', '""').toString(), 'key=""; HttpOnly');
  Expect.equals(Cookie('key', '"value"').toString(), 'key="value"; HttpOnly');
  Expect.equals(Cookie.fromSetCookieValue('key=value; HttpOnly').toString(),
      'key=value; HttpOnly');
  Expect.equals(
      Cookie.fromSetCookieValue('key=; HttpOnly').toString(), 'key=; HttpOnly');
  Expect.equals(Cookie.fromSetCookieValue('key=""; HttpOnly').toString(),
      'key=""; HttpOnly');
  Expect.equals(Cookie.fromSetCookieValue('key="value"; HttpOnly').toString(),
      'key="value"; HttpOnly');
  Expect.throwsFormatException(() => Cookie('key', '"'));
  Expect.throwsFormatException(() => Cookie('key', '"""'));
  Expect.throwsFormatException(() => Cookie('key', '"x""'));
  Expect.throwsFormatException(() => Cookie('key', '"x"y"'));
  Expect.throwsFormatException(
      () => Cookie.fromSetCookieValue('key="; HttpOnly'));
  Expect.throwsFormatException(
      () => Cookie.fromSetCookieValue('key="""; HttpOnly'));
  Expect.throwsFormatException(
      () => Cookie.fromSetCookieValue('key="x""; HttpOnly'));
}

void testValidatePath() {
  Cookie cookie = Cookie.fromSetCookieValue(" cname = cval; path= / ");
  Expect.equals('/', cookie.path);
  cookie.path = null;
  Expect.throws<FormatException>(() {
    cookie.path = "something; ";
  }, (e) => e.toString().contains('Invalid character'));

  StringBuffer buffer = StringBuffer();
  buffer.writeCharCode(0x1f);
  Expect.throws<FormatException>(() {
    cookie.path = buffer.toString();
  }, (e) => e.toString().contains('Invalid character'));

  buffer.clear();
  buffer.writeCharCode(0x7f);
  Expect.throws<FormatException>(() {
    cookie.path = buffer.toString();
  }, (e) => e.toString().contains('Invalid character'));

  buffer.clear();
  buffer.writeCharCode(0x00);
  Expect.throws<FormatException>(() {
    cookie.path = buffer.toString();
  }, (e) => e.toString().contains('Invalid character'));
}

void main() {
  testCookies();
  testValidateCookieWithDoubleQuotes();
  testValidatePath();
}
