// Copyright (c) 2016, 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 'package:path/path.dart' as p;
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:test/test.dart' hide fail;

import 'package:pub/src/utils.dart';

import 'descriptor.dart' as d;

/// The global [DescriptorServer] that's used by default.
///
/// `null` if there's no global server in use. This can be set to replace the
/// existing global server.
DescriptorServer get globalServer => _globalServer;
set globalServer(DescriptorServer value) {
  if (_globalServer == null) {
    addTearDown(() {
      _globalServer = null;
    });
  } else {
    expect(_globalServer.close(), completes);
  }

  _globalServer = value;
}

DescriptorServer _globalServer;

/// Creates a global [DescriptorServer] to serve [contents] as static files.
///
/// This server will exist only for the duration of the pub run. It's accessible
/// via [server]. Subsequent calls to [serve] replace the previous server.
Future serve([List<d.Descriptor> contents]) async {
  globalServer = await DescriptorServer.start(contents);
}

/// Like [serve], but reports an error if a request ever comes in to the server.
Future serveErrors() async {
  globalServer = await DescriptorServer.errors();
}

class DescriptorServer {
  /// The underlying server.
  shelf.Server _server;

  /// A future that will complete to the port used for the server.
  int get port => _server.url.port;

  /// The list of paths that have been requested from this server.
  final requestedPaths = <String>[];

  /// The base directory descriptor of the directories served by [this].
  final d.DirectoryDescriptor _baseDir;

  /// The descriptors served by this server.
  ///
  /// This can safely be modified between requests.
  List<d.Descriptor> get contents => _baseDir.contents;

  /// Creates an HTTP server to serve [contents] as static files.
  ///
  /// This server exists only for the duration of the pub run. Subsequent calls
  /// to [serve] replace the previous server.
  static Future<DescriptorServer> start([List<d.Descriptor> contents]) async =>
      new DescriptorServer._(
          await shelf_io.IOServer.bind('localhost', 0), contents);

  /// Creates a server that reports an error if a request is ever received.
  static Future<DescriptorServer> errors() async =>
      new DescriptorServer._errors(
          await shelf_io.IOServer.bind('localhost', 0));

  DescriptorServer._(this._server, Iterable<d.Descriptor> contents)
      : _baseDir = d.dir("serve-dir", contents) {
    _server.mount((request) async {
      var path = p.posix.fromUri(request.url.path);
      requestedPaths.add(path);

      try {
        var stream = await validateStream(_baseDir.load(path));
        return new shelf.Response.ok(stream);
      } catch (_) {
        return new shelf.Response.notFound('File "$path" not found.');
      }
    });
    addTearDown(() => _server.close());
  }

  DescriptorServer._errors(this._server) : _baseDir = d.dir("serve-dir", []) {
    _server.mount((request) {
      fail("The HTTP server received an unexpected request:\n"
          "${request.method} ${request.requestedUri}");
    });
    addTearDown(() => _server.close());
  }

  /// Closes this server.
  Future close() => _server.close();
}
