library shelf_static;

import 'dart:io';

import 'package:http_parser/http_parser.dart';
import 'package:mime/mime.dart' as mime;
import 'package:path/path.dart' as p;
import 'package:shelf/shelf.dart';

// directory listing
// hidden files

/// Creates a Shelf [Handler] that serves files from the provided
/// [fileSystemPath].
///
/// Accessing a path containing symbolic links will succeed only if the resolved
/// path is within [fileSystemPath]. To allow access to paths outside of
/// [fileSystemPath], set [serveFilesOutsidePath] to `true`.
///
/// When a existing directory is requested and a [defaultDocument] is specified
/// the directory is checked for a file with that name. If it exists, it is
/// served.
Handler createStaticHandler(String fileSystemPath,
    {bool serveFilesOutsidePath: false, String defaultDocument}) {
  var rootDir = new Directory(fileSystemPath);
  if (!rootDir.existsSync()) {
    throw new ArgumentError('A directory corresponding to fileSystemPath '
        '"$fileSystemPath" could not be found');
  }

  fileSystemPath = rootDir.resolveSymbolicLinksSync();

  if (defaultDocument != null) {
    if (defaultDocument != p.basename(defaultDocument)) {
      throw new ArgumentError('defaultDocument must be a file name.');
    }
  }

  return (Request request) {
    // TODO: expand these checks and/or follow updates to Uri class to be more
    //       strict. https://code.google.com/p/dart/issues/detail?id=16081
    if (request.requestedUri.path.contains(' ')) {
      return new Response.forbidden('The requested path is invalid.');
    }

    var segs = [fileSystemPath]..addAll(request.url.pathSegments);

    var requestedPath = p.joinAll(segs);

    var fileType = FileSystemEntity.typeSync(requestedPath, followLinks: true);

    File file = null;

    if (fileType == FileSystemEntityType.FILE) {
      file = new File(requestedPath);
    } else if (fileType == FileSystemEntityType.DIRECTORY) {
      file = _tryDefaultFile(requestedPath, defaultDocument);
    }

    if (file == null) {
      return new Response.notFound('Not Found');
    }

    if (!serveFilesOutsidePath) {
      var resolvedPath = file.resolveSymbolicLinksSync();

      // Do not serve a file outside of the original fileSystemPath
      if (!p.isWithin(fileSystemPath, resolvedPath)) {
        return new Response.notFound('Not Found');
      }
    }

    if (fileType == FileSystemEntityType.DIRECTORY &&
        !request.url.path.endsWith('/')) {
      // when serving the default document for a directory, if the requested
      // path doesn't end with '/', redirect to the path with a trailing '/'
      var uri = request.requestedUri;
      assert(!uri.path.endsWith('/'));
      var location = new Uri(scheme: uri.scheme, userInfo: uri.userInfo,
          host: uri.host, port: uri.port, path: uri.path + '/',
          query: uri.query);

      return new Response.movedPermanently(location.toString());
    }

    var fileStat = file.statSync();

    var ifModifiedSince = request.ifModifiedSince;

    if (ifModifiedSince != null && !fileStat.changed.isAfter(ifModifiedSince)) {
      return new Response.notModified();
    }

    var headers = <String, String>{
      HttpHeaders.CONTENT_LENGTH: fileStat.size.toString(),
      HttpHeaders.LAST_MODIFIED: formatHttpDate(fileStat.changed)
    };

    var contentType = mime.lookupMimeType(requestedPath);

    if (contentType != null) {
      headers[HttpHeaders.CONTENT_TYPE] = contentType;
    }

    return new Response.ok(file.openRead(), headers: headers);
  };
}

File _tryDefaultFile(String dirPath, String defaultFile) {
  if (defaultFile == null) return null;

  var filePath = p.join(dirPath, defaultFile);

  var file = new File(filePath);

  if (file.existsSync()) {
    return file;
  }

  return null;
}

/// Use [createStaticHandler] instead.
@deprecated
Handler getHandler(String fileSystemPath) =>
    createStaticHandler(fileSystemPath);
