// Copyright (c) 2018, 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 "dart:async";
import "dart:io" show Directory, File, Platform;
import "dart:typed_data";

import "package:http_io/http_io.dart";
import "package:test/test.dart";

// Platform.script may refer to a AOT or JIT snapshot, which are significantly
// larger.
File scriptSource;

void testServerRequest(void handler(server, request),
    {int bytes, bool closeClient}) {
  HttpServer.bind("127.0.0.1", 0).then((server) {
    server.defaultResponseHeaders.clear();
    server.listen((request) {
      handler(server, request);
    });

    var client = new HttpClient();
    // We only close the client on either
    // - Bad response headers
    // - Response done (with optional errors in between).
    client
        .get("127.0.0.1", server.port, "/")
        .then((request) => request.close())
        .then((response) {
      int received = 0;
      var subscription;
      subscription = response.listen((data) {
        if (closeClient == true) {
          subscription.cancel();
          client.close();
        } else {
          received += data.length;
        }
      }, onDone: () {
        if (bytes != null) expect(received, equals(bytes));
        client.close();
      }, onError: (error) {
        expect(error is HttpException, isTrue);
      });
    }).catchError((error) {
      client.close();
    }, test: (e) => e is HttpException);
  });
}

Future<List> testResponseDone() {
  final completers = new List<Future<Null>>();
  final completer = new Completer<Null>();
  testServerRequest((server, request) {
    request.response.close();
    request.response.done.then((response) {
      expect(request.response, equals(response));
      server.close();
      completer.complete();
    });
  });
  completers.add(completer.future);

  final completer2 = new Completer<Null>();
  testServerRequest((server, request) {
    new File("__nonexistent_file_")
        .openRead()
        .pipe(request.response)
        .catchError((e) {
      server.close();
      completer2.complete();
    });
  });
  completers.add(completer2.future);

  final completer3 = new Completer<Null>();
  testServerRequest((server, request) {
    request.response.done.then((_) {
      server.close();
      completer3.complete();
    });
    request.response.contentLength = 0;
    request.response.close();
  });
  completers.add(completer3.future);

  return Future.wait(completers);
}

Future<List> testResponseAddStream() {
  File file = scriptSource;
  int bytes = file.lengthSync();
  final completers = new List<Future<Null>>();
  final completer = new Completer<Null>();
  testServerRequest((server, request) {
    request.response.addStream(file.openRead()).then((response) {
      response.close();
      response.done.then((_) {
        server.close();
        completer.complete();
      });
    });
  }, bytes: bytes);
  completers.add(completer.future);

  final completer2 = new Completer<Null>();
  testServerRequest((server, request) {
    request.response.addStream(file.openRead()).then((response) {
      request.response.addStream(file.openRead()).then((response) {
        response.close();
        response.done.then((_) {
          server.close();
          completer2.complete();
        });
      });
    });
  }, bytes: bytes * 2);
  completers.add(completer2.future);

  final completer3 = new Completer<Null>();
  testServerRequest((server, request) {
    var controller = new StreamController(sync: true);
    request.response.addStream(controller.stream).then((response) {
      response.close();
      response.done.then((_) {
        server.close();
        completer3.complete();
      });
    });
    controller.close();
  }, bytes: 0);
  completers.add(completer3.future);

  final completer4 = new Completer<Null>();
  testServerRequest((server, request) {
    request.response
        .addStream(new File("__nonexistent_file_").openRead())
        .catchError((e) {
      server.close();
      completer4.complete();
    });
  });
  completers.add(completer4.future);

  final completer5 = new Completer<Null>();
  testServerRequest((server, request) {
    new File("__nonexistent_file_")
        .openRead()
        .pipe(request.response)
        .catchError((e) {
      server.close();
      completer5.complete();
    });
  });
  completers.add(completer5.future);
  return Future.wait(completers);
}

Future<Null> testResponseAddStreamClosed() {
  final completer = new Completer<Null>();
  File file = scriptSource;
  testServerRequest((server, request) {
    request.response.addStream(file.openRead()).then((response) {
      response.close();
      response.done.then((_) => server.close());
    });
  }, closeClient: true);

  testServerRequest((server, request) {
    int count = 0;
    write() {
      request.response.addStream(file.openRead()).then((response) {
        request.response.write("sync data");
        count++;
        if (count < 1000) {
          write();
        } else {
          response.close();
          response.done.then((_) {
            server.close();
            completer.complete();
          });
        }
      });
    }

    write();
  }, closeClient: true);
  return completer.future;
}

Future<List> testResponseAddClosed() {
  File file = scriptSource;
  final completers = new List<Future<Null>>();

  final completer = new Completer<Null>();
  testServerRequest((server, request) {
    request.response.add(file.readAsBytesSync());
    request.response.close();
    request.response.done.then((_) {
      server.close();
      completer.complete();
    });
  }, closeClient: true);
  completers.add(completer.future);

  final completer2 = new Completer<Null>();
  testServerRequest((server, request) {
    for (int i = 0; i < 1000; i++) {
      request.response.add(file.readAsBytesSync());
    }
    request.response.close();
    request.response.done.then((_) {
      server.close();
      completer2.complete();
    });
  }, closeClient: true);
  completers.add(completer2.future);

  final completer3 = new Completer<Null>();
  testServerRequest((server, request) {
    int count = 0;
    write() {
      request.response.add(file.readAsBytesSync());
      Timer.run(() {
        count++;
        if (count < 1000) {
          write();
        } else {
          request.response.close();
          request.response.done.then((_) {
            server.close();
            completer3.complete();
          });
        }
      });
    }

    write();
  }, closeClient: true);
  completers.add(completer3.future);
  return Future.wait(completers);
}

Future<List> testBadResponseAdd() {
  final completers = new List<Future<Null>>();
  final completer = new Completer<Null>();
  testServerRequest((server, request) {
    request.response.contentLength = 0;
    request.response.add([0]);
    request.response.close();
    request.response.done.catchError((error) {
      server.close();
      completer.complete();
    }, test: (e) => e is HttpException);
  });
  completers.add(completer.future);

  final completer2 = new Completer<Null>();
  testServerRequest((server, request) {
    request.response.contentLength = 5;
    request.response.add([0, 0, 0]);
    request.response.add([0, 0, 0]);
    request.response.close();
    request.response.done.catchError((error) {
      server.close();
      completer2.complete();
    }, test: (e) => e is HttpException);
  });
  completers.add(completer2.future);

  final completer3 = new Completer<Null>();
  testServerRequest((server, request) {
    request.response.contentLength = 0;
    request.response.add(new Uint8List(64 * 1024));
    request.response.add(new Uint8List(64 * 1024));
    request.response.add(new Uint8List(64 * 1024));
    request.response.close();
    request.response.done.catchError((error) {
      server.close();
      completer3.complete();
    }, test: (e) => e is HttpException);
  });
  completers.add(completer3.future);
  return Future.wait(completers);
}

Future<List> testBadResponseClose() {
  final completers = new List<Future<Null>>();
  final completer = new Completer<Null>();
  testServerRequest((server, request) {
    request.response.contentLength = 5;
    request.response.close();
    request.response.done.catchError((error) {
      server.close();
      completer.complete();
    }, test: (e) => e is HttpException);
  });
  completers.add(completer.future);

  final completer2 = new Completer<Null>();
  testServerRequest((server, request) {
    request.response.contentLength = 5;
    request.response.add([0]);
    request.response.close();
    request.response.done.catchError((error) {
      server.close();
      completer2.complete();
    }, test: (e) => e is HttpException);
  });
  completers.add(completer2.future);
  return Future.wait(completers);
}

Future<Null> testIgnoreRequestData() {
  final completer = new Completer<Null>();
  HttpServer.bind("127.0.0.1", 0).then((server) {
    server.listen((request) {
      // Ignore request data.
      request.response.write("all-okay");
      request.response.close();
    });

    var client = new HttpClient();
    client.get("127.0.0.1", server.port, "/").then((request) {
      request.contentLength = 1024 * 1024;
      request.add(new Uint8List(1024 * 1024));
      return request.close();
    }).then((response) {
      response.fold(0, (s, b) => s + b.length).then((bytes) {
        expect(8, equals(bytes));
        server.close();
        completer.complete();
      });
    });
  });
  return completer.future;
}

Future<Null> testWriteCharCode() {
  final completer = new Completer<Null>();
  testServerRequest((server, request) {
    // Test that default is latin-1 (only 2 bytes).
    request.response.writeCharCode(0xFF);
    request.response.writeCharCode(0xFF);
    request.response.close().then((_) {
      server.close();
      completer.complete();
    });
  }, bytes: 2);
  return completer.future;
}

void main() {
  scriptSource =
      new File('${Directory.current.path}/test/http_server_response_test.dart');
  if (!scriptSource.existsSync()) {
    // If we can't find the file relative to the cwd, then look relative
    // to Platform.script.
    scriptSource = new File(
        Platform.script.resolve('http_server_response_test.dart').toFilePath());
  }
  test('responseDone', () => testResponseDone());
  test('responseAddStream', () => testResponseAddStream());
  test('responseAddStreamClosed', () => testResponseAddStreamClosed());
  test('responseAddClosed', () => testResponseAddClosed());
  test('badResponseAdd', () => testBadResponseAdd());
  test('badResponseClose', () => testBadResponseClose());
  test('ignoreRequestData', () => testIgnoreRequestData());
  test('writeCharCode', () => testWriteCharCode());
}
