// 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 'dart:async';
import 'dart:io';

import "package:http_server/http_server.dart";
import "package:path/path.dart";
import "package:unittest/unittest.dart";

import 'utils.dart';


void main() {
  group('serve-root', () {
    test('dir-exists', () {
      expect(HttpServer.bind('localhost', 0).then((server) {
        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
        var virDir = new VirtualDirectory(dir.path);

        virDir.serve(server);

        return getStatusCode(server.port, '/')
            .whenComplete(() {
              server.close();
              dir.deleteSync();
            });
      }), completion(equals(HttpStatus.NOT_FOUND)));
    });

    test('dir-not-exists', () {
      expect(HttpServer.bind('localhost', 0).then((server) {
        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
        dir.deleteSync();
        var virDir = new VirtualDirectory(dir.path);

        virDir.serve(server);

        return getStatusCode(server.port, '/')
            .whenComplete(() {
              server.close();
            });
      }), completion(equals(HttpStatus.NOT_FOUND)));
    });
  });

  group('serve-file', () {
    group('top-level', () {
      test('file-exists', () {
        expect(HttpServer.bind('localhost', 0).then((server) {
          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
          var file = new File('${dir.path}/file')..createSync();
          var virDir = new VirtualDirectory(dir.path);

          virDir.serve(server);

          return getStatusCode(server.port, '/file')
              .whenComplete(() {
                server.close();
                dir.deleteSync(recursive: true);
              });
        }), completion(equals(HttpStatus.OK)));
      });

      test('file-not-exists', () {
        expect(HttpServer.bind('localhost', 0).then((server) {
          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
          var virDir = new VirtualDirectory(dir.path);

          virDir.serve(server);

          return getStatusCode(server.port, '/file')
              .whenComplete(() {
                server.close();
                dir.deleteSync();
              });
        }), completion(equals(HttpStatus.NOT_FOUND)));
      });
    });

    group('in-dir', () {
      test('file-exists', () {
        expect(HttpServer.bind('localhost', 0).then((server) {
          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
          var dir2 = new Directory('${dir.path}/dir')..createSync();
          var file = new File('${dir2.path}/file')..createSync();
          var virDir = new VirtualDirectory(dir.path);

          virDir.serve(server);

          return getStatusCode(server.port, '/dir/file')
              .whenComplete(() {
                server.close();
                dir.deleteSync(recursive: true);
              });
        }), completion(equals(HttpStatus.OK)));
      });

      test('file-not-exists', () {
        expect(HttpServer.bind('localhost', 0).then((server) {
          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
          var dir2 = new Directory('${dir.path}/dir')..createSync();
          var file = new File('${dir.path}/file')..createSync();
          var virDir = new VirtualDirectory(dir.path);

          virDir.serve(server);

          return getStatusCode(server.port, '/dir/file')
              .whenComplete(() {
                server.close();
                dir.deleteSync(recursive: true);
              });
        }), completion(equals(HttpStatus.NOT_FOUND)));
      });
    });
  });

  group('serve-dir', () {
    group('top-level', () {
      test('simple', () {
        expect(HttpServer.bind('localhost', 0).then((server) {
          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
          var virDir = new VirtualDirectory(dir.path);
          virDir.allowDirectoryListing = true;

          virDir.serve(server);

          return getAsString(server.port, '/')
          .whenComplete(() {
            server.close();
            dir.deleteSync();
          });
        }), completion(contains('Index of /')));
      });

      test('files', () {
        expect(HttpServer.bind('localhost', 0).then((server) {
          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
          var virDir = new VirtualDirectory(dir.path);
          for (int i = 0; i < 10; i++) {
            new File('${dir.path}/$i').createSync();
          }
          virDir.allowDirectoryListing = true;

          virDir.serve(server);

          return getAsString(server.port, '/')
          .whenComplete(() {
            server.close();
            dir.deleteSync(recursive: true);
          });
        }), completion(contains('Index of /')));
      });

      test('dirs', () {
        expect(HttpServer.bind('localhost', 0).then((server) {
          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
          var virDir = new VirtualDirectory(dir.path);
          for (int i = 0; i < 10; i++) {
            new Directory('${dir.path}/$i').createSync();
          }
          virDir.allowDirectoryListing = true;

          virDir.serve(server);

          return getAsString(server.port, '/')
          .whenComplete(() {
            server.close();
            dir.deleteSync(recursive: true);
          });
        }), completion(contains('Index of /')));
      });

      if (!Platform.isWindows) {
        test('recursive-link', () {
          expect(HttpServer.bind('localhost', 0).then((server) {
            var dir =
                Directory.systemTemp.createTempSync('http_server_virtual_');
            var link = new Link('${dir.path}/recursive')..createSync('.');
            var virDir = new VirtualDirectory(dir.path);
            virDir.allowDirectoryListing = true;

            virDir.serve(server);

            return Future.wait([
                getAsString(server.port, '/').then(
                    (s) => s.contains('recursive/')),
                getAsString(server.port, '/').then(
                    (s) => !s.contains('../')),
                getAsString(server.port, '/').then(
                    (s) => s.contains('Index of /')),
                getAsString(server.port, '/recursive').then(
                    (s) => s.contains('recursive/')),
                getAsString(server.port, '/recursive').then(
                    (s) => s.contains('../')),
                getAsString(server.port, '/recursive').then(
                    (s) => s.contains('Index of /recursive'))])
                .whenComplete(() {
                  server.close();
                  dir.deleteSync(recursive: true);
                });
          }), completion(equals([true, true, true, true, true, true])));
        });
      }
    });

    group('custom', () {
      test('simple', () {
        expect(HttpServer.bind('localhost', 0).then((server) {
          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
          var virDir = new VirtualDirectory(dir.path);
          virDir.allowDirectoryListing = true;
          virDir.setDirectoryHandler((dir2, request) {
            expect(dir2, isNotNull);
            expect(FileSystemEntity.identicalSync(dir.path, dir2.path), isTrue);
            request.response.write('My handler ${request.uri.path}');
            request.response.close();
          });

          virDir.serve(server);

          return getAsString(server.port, '/')
          .whenComplete(() {
            server.close();
            dir.deleteSync();
          });
        }), completion(contains('My handler /')));
      });
    });
  });

  group('links', () {
    if (!Platform.isWindows) {
      group('follow-links', () {
        test('dir-link', () {
          expect(HttpServer.bind('localhost', 0).then((server) {
            var dir =
                Directory.systemTemp.createTempSync('http_server_virtual_');
            var dir2 = new Directory('${dir.path}/dir2')..createSync();
            var link = new Link('${dir.path}/dir3')..createSync('dir2');
            var file = new File('${dir2.path}/file')..createSync();
            var virDir = new VirtualDirectory(dir.path);
            virDir.followLinks = true;

            virDir.serve(server);

            return getStatusCode(server.port, '/dir3/file')
                .whenComplete(() {
                  server.close();
                  dir.deleteSync(recursive: true);
                });
          }), completion(equals(HttpStatus.OK)));
        });

        test('root-link', () {
          expect(HttpServer.bind('localhost', 0).then((server) {
            var dir =
                Directory.systemTemp.createTempSync('http_server_virtual_');
            var link = new Link('${dir.path}/dir3')..createSync('.');
            var file = new File('${dir.path}/file')..createSync();
            var virDir = new VirtualDirectory(dir.path);
            virDir.followLinks = true;

            virDir.serve(server);

            return getStatusCode(server.port, '/dir3/file')
                .whenComplete(() {
                  server.close();
                  dir.deleteSync(recursive: true);
                });
          }), completion(equals(HttpStatus.OK)));
        });

        group('bad-links', () {
          test('absolute-link', () {
            expect(HttpServer.bind('localhost', 0).then((server) {
              var dir =
                  Directory.systemTemp.createTempSync('http_server_virtual_');
              var file = new File('${dir.path}/file')..createSync();
              var link = new Link('${dir.path}/dir3')
                  ..createSync('${dir.path}/file');
              var virDir = new VirtualDirectory(dir.path);
              virDir.followLinks = true;

              virDir.serve(server);

              return new HttpClient().get('localhost',
                                          server.port,
                                          '/dir3/file')
                  .then((request) => request.close())
                  .then((response) => response.drain().then(
                      (_) => response.statusCode))
                  .whenComplete(() {
                    server.close();
                    dir.deleteSync(recursive: true);
                  });
            }), completion(equals(HttpStatus.NOT_FOUND)));
          });

          test('relative-parent-link', () {
            expect(HttpServer.bind('localhost', 0).then((server) {
              var dir =
                  Directory.systemTemp.createTempSync('http_server_virtual_');
              var name = basename(dir.path);
              var file = new File('${dir.path}/file')..createSync();
              var link = new Link('${dir.path}/dir3')
                  ..createSync('../$name/file');
              var virDir = new VirtualDirectory(dir.path);
              virDir.followLinks = true;

              virDir.serve(server);

              return new HttpClient().get('localhost',
                                          server.port,
                                          '/dir3/file')
                  .then((request) => request.close())
                  .then((response) => response.drain().then(
                      (_) => response.statusCode))
                  .whenComplete(() {
                    server.close();
                    dir.deleteSync(recursive: true);
                  });
            }), completion(equals(HttpStatus.NOT_FOUND)));
          });
        });
      });

      group('not-follow-links', () {
        test('dir-link', () {
          expect(HttpServer.bind('localhost', 0).then((server) {
            var dir =
                Directory.systemTemp.createTempSync('http_server_virtual_');
            var dir2 = new Directory('${dir.path}/dir2')..createSync();
            var link = new Link('${dir.path}/dir3')..createSync('dir2');
            var file = new File('${dir2.path}/file')..createSync();
            var virDir = new VirtualDirectory(dir.path);
            virDir.followLinks = false;

            virDir.serve(server);

            return getStatusCode(server.port, '/dir3/file')
                .whenComplete(() {
                  server.close();
                  dir.deleteSync(recursive: true);
                });
          }), completion(equals(HttpStatus.NOT_FOUND)));
        });
      });
    }
  });

  group('last-modified', () {
    group('file', () {
      test('file-exists', () {
        expect(HttpServer.bind('localhost', 0).then((server) {
          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
          var file = new File('${dir.path}/file')..createSync();
          var virDir = new VirtualDirectory(dir.path);

          virDir.serve(server);

          return getHeaders(server.port, '/file')
              .then((headers) {
                expect(headers.value(HttpHeaders.LAST_MODIFIED), isNotNull);
                return HttpDate.parse(
                    headers.value(HttpHeaders.LAST_MODIFIED));
              })
              .then((lastModified) {
                return getStatusCode(
                    server.port, '/file', ifModifiedSince: lastModified);
              })
              .whenComplete(() {
                server.close();
                dir.deleteSync(recursive: true);
              });
        }), completion(equals(HttpStatus.NOT_MODIFIED)));
      });

      test('file-changes', () {
        expect(HttpServer.bind('localhost', 0).then((server) {
          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
          var file = new File('${dir.path}/file')..createSync();
          var virDir = new VirtualDirectory(dir.path);

          virDir.serve(server);

          return getHeaders(server.port, '/file')
              .then((headers) {
                expect(headers.value(HttpHeaders.LAST_MODIFIED), isNotNull);
                return HttpDate.parse(
                    headers.value(HttpHeaders.LAST_MODIFIED));
              })
              .then((lastModified) {
                // Fake file changed by moving date back in time.
                lastModified = lastModified.subtract(
                  const Duration(seconds: 10));
                return getStatusCode(
                    server.port, '/file', ifModifiedSince: lastModified);
              })
              .whenComplete(() {
                server.close();
                dir.deleteSync(recursive: true);
              });
        }), completion(equals(HttpStatus.OK)));
      });
    });
  });

  group('content-type', () {
    group('mime-type', () {
      test('from-path', () {
        expect(HttpServer.bind('localhost', 0).then((server) {
          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
          var file = new File('${dir.path}/file.jpg')..createSync();
          var virDir = new VirtualDirectory(dir.path);

          virDir.serve(server);

          return getHeaders(server.port, '/file.jpg')
              .then((headers) => headers.contentType.toString())
              .whenComplete(() {
                server.close();
                dir.deleteSync(recursive: true);
              });
        }), completion(equals('image/jpeg')));
      });

      test('from-magic-number', () {
        expect(HttpServer.bind('localhost', 0).then((server) {
          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
          var file = new File('${dir.path}/file.jpg')..createSync();
          file.writeAsBytesSync(
              [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]);
          var virDir = new VirtualDirectory(dir.path);

          virDir.serve(server);

          return getHeaders(server.port, '/file.jpg')
              .then((headers) => headers.contentType.toString())
              .whenComplete(() {
                server.close();
                dir.deleteSync(recursive: true);
              });
        }), completion(equals('image/png')));
      });
    });
  });

  group('error-page', () {
    test('default', () {
      expect(HttpServer.bind('localhost', 0).then((server) {
        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
        var virDir = new VirtualDirectory(dir.path);
        dir.deleteSync();

        virDir.serve(server);

        return getAsString(server.port, '/')
            .whenComplete(() {
              server.close();
            });
      }), completion(matches(new RegExp('404.*Not Found'))));
    });

    test('custom', () {
      expect(HttpServer.bind('localhost', 0).then((server) {
        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
        var virDir = new VirtualDirectory(dir.path);
        dir.deleteSync();

        virDir.setErrorPageHandler((request) {
          request.response.write('my-page ');
          request.response.write(request.response.statusCode);
          request.response.close();
        });
        virDir.serve(server);

        return getAsString(server.port, '/')
            .whenComplete(() {
              server.close();
            });
      }), completion(equals('my-page 404')));
    });
  });

  group('escape-root', () {
    test('escape1', () {
      expect(HttpServer.bind('localhost', 0).then((server) {
        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
        var virDir = new VirtualDirectory(dir.path);
        virDir.allowDirectoryListing = true;

        virDir.serve(server);

        return getStatusCode(server.port, '/../')
            .whenComplete(() {
              server.close();
              dir.deleteSync();
            });
      }), completion(equals(HttpStatus.NOT_FOUND)));
    });

    test('escape2', () {
      expect(HttpServer.bind('localhost', 0).then((server) {
        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
        new Directory('${dir.path}/dir').createSync();
        var virDir = new VirtualDirectory(dir.path);
        virDir.allowDirectoryListing = true;

        virDir.serve(server);

        return getStatusCode(server.port, '/dir/../../')
            .whenComplete(() {
              server.close();
              dir.deleteSync(recursive: true);
            });
      }), completion(equals(HttpStatus.NOT_FOUND)));
    });
  });

  group('url-decode', () {
    test('with-space', () {
      expect(HttpServer.bind('localhost', 0).then((server) {
        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
        var file = new File('${dir.path}/my file')..createSync();
        var virDir = new VirtualDirectory(dir.path);

        virDir.serve(server);

        return getStatusCode(server.port, '/my file')
            .whenComplete(() {
              server.close();
              dir.deleteSync(recursive: true);
            });
      }), completion(equals(HttpStatus.OK)));
    });

    test('encoded-space', () {
      expect(HttpServer.bind('localhost', 0).then((server) {
        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
        var file = new File('${dir.path}/my file')..createSync();
        var virDir = new VirtualDirectory(dir.path);

        virDir.serve(server);

        return getStatusCode(server.port, '/my%20file')
            .whenComplete(() {
              server.close();
              dir.deleteSync(recursive: true);
            });
      }), completion(equals(HttpStatus.NOT_FOUND)));
    });

    test('encoded-path-separator', () {
      expect(HttpServer.bind('localhost', 0).then((server) {
        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
        new Directory('${dir.path}/a').createSync();
        new Directory('${dir.path}/a/b').createSync();
        new Directory('${dir.path}/a/b/c').createSync();
        var virDir = new VirtualDirectory(dir.path);
        virDir.allowDirectoryListing = true;

        virDir.serve(server);

        return getStatusCode(server.port, '/a%2fb/c', rawPath: true)
            .whenComplete(() {
              server.close();
              dir.deleteSync(recursive: true);
            });
      }), completion(equals(HttpStatus.NOT_FOUND)));
    });

    test('encoded-null', () {
      expect(HttpServer.bind('localhost', 0).then((server) {
        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
        var virDir = new VirtualDirectory(dir.path);
        virDir.allowDirectoryListing = true;

        virDir.serve(server);

        return getStatusCode(server.port, '/%00', rawPath: true)
            .whenComplete(() {
              server.close();
              dir.deleteSync(recursive: true);
            });
      }), completion(equals(HttpStatus.NOT_FOUND)));
    });

    testEncoding(name, expected, [bool create = true]) {
      test('encode-$name', () {
        expect(HttpServer.bind('localhost', 0).then((server) {
        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
          if (create) new File('${dir.path}/$name').createSync();
          var virDir = new VirtualDirectory(dir.path);
          virDir.allowDirectoryListing = true;

          virDir.serve(server);

          return getStatusCode(server.port, '/$name')
              .whenComplete(() {
                server.close();
                dir.deleteSync(recursive: true);
              });
        }), completion(equals(expected)));
      });
    }
    testEncoding('..', HttpStatus.NOT_FOUND, false);
    testEncoding('%2e%2e', HttpStatus.OK);
    testEncoding('%252e%252e', HttpStatus.OK);
    testEncoding('/', HttpStatus.OK, false);
    testEncoding('%2f', HttpStatus.NOT_FOUND, false);
    testEncoding('%2f', HttpStatus.OK, true);
  });
}

