// 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.

import "package:expect/expect.dart";
import 'dart:async';
import 'dart:io';

const SESSION_ID = "DARTSESSID";

String getSessionId(List<Cookie> cookies) {
  var id = cookies.fold<String?>(null, (last, cookie) {
    if (last != null) return last;
    if (cookie.name.toUpperCase() == SESSION_ID) {
      Expect.isTrue(cookie.httpOnly);
      return cookie.value;
    }
    return null;
  });
  Expect.isNotNull(id);
  return id!;
}

Future<String> connectGetSession(HttpClient client, int port,
    [String? session]) {
  return client.get("127.0.0.1", port, "/").then((request) {
    if (session != null) {
      request.cookies.add(new Cookie(SESSION_ID, session));
    }
    return request.close();
  }).then((response) {
    return response.fold(getSessionId(response.cookies), (v, _) => v);
  });
}

void testSessions(int sessionCount) {
  var client = new HttpClient();
  HttpServer.bind("127.0.0.1", 0).then((server) {
    var sessions = new Set();
    server.listen((request) {
      sessions.add(request.session.id);
      request.response.close();
    });

    var futures = <Future>[];
    for (int i = 0; i < sessionCount; i++) {
      futures.add(connectGetSession(client, server.port).then((session) {
        Expect.isNotNull(session);
        Expect.isTrue(sessions.contains(session));
        return connectGetSession(client, server.port, session).then((session2) {
          Expect.equals(session2, session);
          Expect.isTrue(sessions.contains(session2));
          return session2;
        });
      }));
    }
    Future.wait(futures).then((clientSessions) {
      Expect.equals(sessions.length, sessionCount);
      Expect.setEquals(new Set.from(clientSessions), sessions);
      server.close();
      client.close();
    });
  });
}

void testTimeout(int sessionCount) {
  var client = new HttpClient();
  HttpServer.bind("127.0.0.1", 0).then((server) {
    server.sessionTimeout = 1;
    var timeouts = <Future>[];
    server.listen((request) {
      var c = new Completer();
      timeouts.add(c.future);
      request.session.onTimeout = () {
        c.complete(null);
      };
      request.response.close();
    });

    var futures = <Future>[];
    for (int i = 0; i < sessionCount; i++) {
      futures.add(connectGetSession(client, server.port));
    }
    Future.wait(futures).then((clientSessions) {
      Future.wait(timeouts).then((_) {
        futures = <Future>[];
        for (var id in clientSessions) {
          futures
              .add(connectGetSession(client, server.port, id).then((session) {
            Expect.isNotNull(session);
            Expect.notEquals(id, session);
          }));
        }
        Future.wait(futures).then((_) {
          server.close();
          client.close();
        });
      });
    });
  });
}

void testSessionsData() {
  HttpServer.bind("127.0.0.1", 0).then((server) {
    bool firstHit = false;
    bool secondHit = false;
    server.listen((request) {
      var c = new Completer();
      var session = request.session;
      if (session.isNew) {
        Expect.isFalse(firstHit);
        Expect.isFalse(secondHit);
        firstHit = true;
        session["data"] = "some data";
      } else {
        Expect.isTrue(firstHit);
        Expect.isFalse(secondHit);
        secondHit = true;
        Expect.isTrue(session.containsKey("data"));
        Expect.equals("some data", session["data"]);
      }
      request.response.close();
    });

    var client = new HttpClient();
    client
        .get("127.0.0.1", server.port, "/")
        .then((request) => request.close())
        .then((response) {
      response.listen((_) {}, onDone: () {
        var id = getSessionId(response.cookies);
        Expect.isNotNull(id);
        client.get("127.0.0.1", server.port, "/").then((request) {
          request.cookies.add(new Cookie(SESSION_ID, id));
          return request.close();
        }).then((response) {
          response.listen((_) {}, onDone: () {
            Expect.isTrue(firstHit);
            Expect.isTrue(secondHit);
            Expect.equals(id, getSessionId(response.cookies));
            server.close();
            client.close();
          });
        });
      });
    });
  });
}

void testSessionsDestroy() {
  HttpServer.bind("127.0.0.1", 0).then((server) {
    bool firstHit = false;
    server.listen((request) {
      var session = request.session;
      if (session.isNew) {
        Expect.isFalse(firstHit);
        firstHit = true;
      } else {
        Expect.isTrue(firstHit);
        session.destroy();
        var session2 = request.session;
        Expect.notEquals(session.id, session2.id);
      }
      ;
      request.response.close();
    });

    var client = new HttpClient();
    client
        .get("127.0.0.1", server.port, "/")
        .then((request) => request.close())
        .then((response) {
      response.listen((_) {}, onDone: () {
        var id = getSessionId(response.cookies);
        Expect.isNotNull(id);
        client.get("127.0.0.1", server.port, "/").then((request) {
          request.cookies.add(new Cookie(SESSION_ID, id));
          return request.close();
        }).then((response) {
          response.listen((_) {}, onDone: () {
            Expect.isTrue(firstHit);
            Expect.notEquals(id, getSessionId(response.cookies));
            server.close();
            client.close();
          });
        });
      });
    });
  });
}

void main() {
  testSessions(1);
  testTimeout(5);
  testSessionsData();
  testSessionsDestroy();
}
