// Copyright (c) 2015, 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:convert';
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_static/shelf_static.dart';
import 'package:test/test.dart';
import 'package:test_descriptor/test_descriptor.dart' as d;

import 'test_util.dart';

void main() {
  setUp(() async {
    await d.file('index.html', '<html></html>').create();
    await d.file('root.txt', 'root txt').create();
    await d.file('random.unknown', 'no clue').create();

    const pngBytesContent =
        r'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAABmJLR0QA/wD/AP+gvae'
        r'TAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AYRETkSXaxBzQAAAB1pVFh0Q2'
        r'9tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAbUlEQVQI1wXBvwpBYRwA0'
        r'HO/kjBKJmXRLWXxJ4PsnsMTeAEPILvNZrybF7B4A6XvQW6k+DkHwqgM1TnMpoEoDMtw'
        r'OJE7pB/VXmF3CdseucmjxaAruR41Pl9p/Gbyoq5B9FeL2OR7zJ+3aC/X8QdQCyIArPs'
        r'HkQAAAABJRU5ErkJggg==';

    const webpBytesContent =
        r'UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAQAcJaQAA3AA/v3AgAA=';

    await d.dir('files', [
      d.file('test.txt', 'test txt content'),
      d.file('with space.txt', 'with space content'),
      d.file('header_bytes_test_image', base64Decode(pngBytesContent)),
      d.file('header_bytes_test_webp', base64Decode(webpBytesContent))
    ]).create();
  });

  test('access root file', () async {
    final handler = createStaticHandler(d.sandbox);

    final response = await makeRequest(handler, '/root.txt');
    expect(response.statusCode, HttpStatus.ok);
    expect(response.contentLength, 8);
    expect(response.readAsString(), completion('root txt'));
  });

  test('access root file with space', () async {
    final handler = createStaticHandler(d.sandbox);

    final response = await makeRequest(handler, '/files/with%20space.txt');
    expect(response.statusCode, HttpStatus.ok);
    expect(response.contentLength, 18);
    expect(response.readAsString(), completion('with space content'));
  });

  test('access root file with unencoded space', () async {
    final handler = createStaticHandler(d.sandbox);

    final response = await makeRequest(handler, '/files/with%20space.txt');
    expect(response.statusCode, HttpStatus.ok);
    expect(response.contentLength, 18);
    expect(response.readAsString(), completion('with space content'));
  });

  test('access file under directory', () async {
    final handler = createStaticHandler(d.sandbox);

    final response = await makeRequest(handler, '/files/test.txt');
    expect(response.statusCode, HttpStatus.ok);
    expect(response.contentLength, 16);
    expect(response.readAsString(), completion('test txt content'));
  });

  test('file not found', () async {
    final handler = createStaticHandler(d.sandbox);

    final response = await makeRequest(handler, '/not_here.txt');
    expect(response.statusCode, HttpStatus.notFound);
  });

  test('last modified', () async {
    final handler = createStaticHandler(d.sandbox);

    final rootPath = p.join(d.sandbox, 'root.txt');
    final modified = File(rootPath).statSync().modified.toUtc();

    final response = await makeRequest(handler, '/root.txt');
    expect(response.lastModified, atSameTimeToSecond(modified));
  });

  group('if modified since', () {
    test('same as last modified', () async {
      final handler = createStaticHandler(d.sandbox);

      final rootPath = p.join(d.sandbox, 'root.txt');
      final modified = File(rootPath).statSync().modified.toUtc();

      final headers = {
        HttpHeaders.ifModifiedSinceHeader: formatHttpDate(modified)
      };

      final response =
          await makeRequest(handler, '/root.txt', headers: headers);
      expect(response.statusCode, HttpStatus.notModified);
      expect(response.contentLength, 0);
    });

    test('before last modified', () async {
      final handler = createStaticHandler(d.sandbox);

      final rootPath = p.join(d.sandbox, 'root.txt');
      final modified = File(rootPath).statSync().modified.toUtc();

      final headers = {
        HttpHeaders.ifModifiedSinceHeader:
            formatHttpDate(modified.subtract(const Duration(seconds: 1)))
      };

      final response =
          await makeRequest(handler, '/root.txt', headers: headers);
      expect(response.statusCode, HttpStatus.ok);
      expect(response.lastModified, atSameTimeToSecond(modified));
    });

    test('after last modified', () async {
      final handler = createStaticHandler(d.sandbox);

      final rootPath = p.join(d.sandbox, 'root.txt');
      final modified = File(rootPath).statSync().modified.toUtc();

      final headers = {
        HttpHeaders.ifModifiedSinceHeader:
            formatHttpDate(modified.add(const Duration(seconds: 1)))
      };

      final response =
          await makeRequest(handler, '/root.txt', headers: headers);
      expect(response.statusCode, HttpStatus.notModified);
      expect(response.contentLength, 0);
    });

    test('after file modification', () async {
      // This test updates a file on disk to ensure the file stamp is updated
      // which was previously not the case on Windows due to the files "changed"
      // date being the creation date.
      // https://github.com/dart-lang/shelf_static/issues/37

      final handler = createStaticHandler(d.sandbox);
      final rootPath = p.join(d.sandbox, 'root.txt');

      final response1 = await makeRequest(handler, '/root.txt');
      final originalModificationDate = response1.lastModified!;

      // Ensure the timestamp change is > 1s.
      await Future<void>.delayed(const Duration(seconds: 2));
      File(rootPath).writeAsStringSync('updated root txt');

      final headers = {
        HttpHeaders.ifModifiedSinceHeader:
            formatHttpDate(originalModificationDate)
      };

      final response2 =
          await makeRequest(handler, '/root.txt', headers: headers);
      expect(response2.statusCode, HttpStatus.ok);
      expect(response2.lastModified!.millisecondsSinceEpoch,
          greaterThan(originalModificationDate.millisecondsSinceEpoch));
    });
  });

  group('content type', () {
    test('root.txt should be text/plain', () async {
      final handler = createStaticHandler(d.sandbox);

      final response = await makeRequest(handler, '/root.txt');
      expect(response.mimeType, 'text/plain');
    });

    test('index.html should be text/html', () async {
      final handler = createStaticHandler(d.sandbox);

      final response = await makeRequest(handler, '/index.html');
      expect(response.mimeType, 'text/html');
    });

    test('random.unknown should be null', () async {
      final handler = createStaticHandler(d.sandbox);

      final response = await makeRequest(handler, '/random.unknown');
      expect(response.mimeType, isNull);
    });

    test('header_bytes_test_image should be image/png', () async {
      final handler =
          createStaticHandler(d.sandbox, useHeaderBytesForContentType: true);

      final response =
          await makeRequest(handler, '/files/header_bytes_test_image');
      expect(response.mimeType, 'image/png');
    });

    test('header_bytes_test_webp should be image/webp', () async {
      final resolver = mime.MimeTypeResolver()
        ..addMagicNumber(
          <int>[
            0x52, 0x49, 0x46, 0x46, 0x00, 0x00, //
            0x00, 0x00, 0x57, 0x45, 0x42, 0x50
          ],
          'image/webp',
          mask: <int>[
            0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, //
            0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF
          ],
        );
      final handler = createStaticHandler(d.sandbox,
          useHeaderBytesForContentType: true, contentTypeResolver: resolver);

      final response =
          await makeRequest(handler, '/files/header_bytes_test_webp');
      expect(response.mimeType, 'image/webp');
    });
  });
}
