// Copyright (c) 2019, 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.

@Retry(0)
library;

import 'dart:async';
import 'dart:io';

import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'package:webdev/src/serve/utils.dart';

void main() {
  late Directory from;
  late Directory to;

  setUp(() {
    from = Directory.systemTemp.createTempSync('from');
    to = Directory.systemTemp.createTempSync('to');
  });

  tearDown(() {
    from.deleteSync(recursive: true);
    to.deleteSync(recursive: true);
  });

  test('updatePath does nothing for non-existing directories', () async {
    final subDirFrom = Directory(p.join(from.path, '1'));
    final subDirTo = Directory(p.join(to.path, '2'));

    expect(subDirFrom.existsSync(), isFalse);
    expect(subDirTo.existsSync(), isFalse);

    await updatePath(subDirFrom.path, subDirTo.path);

    expect(subDirFrom.existsSync(), isFalse);
    expect(subDirTo.existsSync(), isFalse);
  });

  test('updatePath creates non-existing directories', () async {
    final subDirFrom = Directory(p.join(from.path, '1'));
    final subDirTo = Directory(p.join(to.path, '2'));

    subDirFrom.createSync();

    expect(subDirFrom.existsSync(), isTrue);
    expect(subDirTo.existsSync(), isFalse);

    await updatePath(subDirFrom.path, subDirTo.path);

    expect(subDirFrom.existsSync(), isTrue);
    expect(subDirTo.existsSync(), isTrue);
  });

  test('updatePath removes stale directories', () async {
    final subDirFrom = Directory(p.join(from.path, '1'));
    final subDirTo = Directory(p.join(to.path, '2'));

    subDirTo.createSync();

    expect(subDirFrom.existsSync(), isFalse);
    expect(subDirTo.existsSync(), isTrue);

    await updatePath(from.path, to.path);

    expect(subDirFrom.existsSync(), isFalse);
    expect(subDirTo.existsSync(), isFalse);
  });

  test('updatePath updates directories', () async {
    final subDirFrom = Directory(p.join(from.path, '1'));
    final subDirTo = Directory(p.join(to.path, '2'));

    subDirFrom.createSync();
    subDirTo.createSync();

    final listFrom =
        from.listSync().map((e) => p.relative(e.path, from: from.path));
    await updatePath(from.path, to.path);

    final listTo = to.listSync().map((e) => p.relative(e.path, from: to.path));
    expect(listFrom, listTo);
  });

  test('updatePath updates files', () async {
    final fileFrom = File(p.join(from.path, '1'));
    final fileTo = File(p.join(to.path, '2'));

    fileFrom.createSync();
    fileTo.createSync();

    final listFrom =
        from.listSync().map((e) => p.relative(e.path, from: from.path));
    await updatePath(from.path, to.path);

    final listTo = to.listSync().map((e) => p.relative(e.path, from: to.path));
    expect(listFrom, listTo);
  });

  test('updatePath updates files and directories', () async {
    final subDirFrom = Directory(p.join(from.path, '1'));
    final subDirTo1 = Directory(p.join(to.path, '1'));
    final subDirTo2 = Directory(p.join(to.path, '2'));

    subDirFrom.createSync();
    subDirTo1.createSync();
    subDirTo2.createSync();

    final fileFrom = File(p.join(subDirFrom.path, 'a'));
    final fileTo1 = File(p.join(subDirTo1.path, 'b'));
    final fileTo2 = File(p.join(subDirTo2.path, 'b'));

    fileFrom.createSync();
    fileTo1.createSync();
    fileTo2.createSync();

    final listFrom = from
        .listSync(recursive: true)
        .map((e) => p.relative(e.path, from: from.path));
    await updatePath(from.path, to.path);

    final listTo = to
        .listSync(recursive: true)
        .map((e) => p.relative(e.path, from: to.path));
    expect(listFrom, listTo);
  });

  test('updatePath updates stale files', () async {
    final fileFrom = File(p.join(from.path, '1'));
    final fileTo = File(p.join(to.path, '1'));

    fileTo.writeAsStringSync('contentsTo');
    await Future.delayed(const Duration(seconds: 1));
    fileFrom.writeAsStringSync('contentsFrom');

    final stats = fileFrom.statSync();
    expect(fileTo.statSync().modified, isNot(equals(stats.modified)));

    expect(fileTo.readAsStringSync(), equals('contentsTo'));
    await updatePath(from.path, to.path);
    expect(fileTo.readAsStringSync(), equals('contentsFrom'));
  });

  test('updatePath does not update newer files', () async {
    final fileFrom = File(p.join(from.path, '1'));
    final fileTo = File(p.join(to.path, '1'));

    fileFrom.writeAsStringSync('contentsFrom');
    await Future.delayed(const Duration(seconds: 1));
    fileTo.writeAsStringSync('contentsTo');

    final stats = fileFrom.statSync();
    expect(fileTo.statSync().modified, isNot(equals(stats.modified)));

    await updatePath(from.path, to.path);
    expect(fileTo.statSync().modified, isNot(equals(stats.modified)));
    expect(fileTo.readAsStringSync(), equals('contentsTo'));
  });

  test('updatePath updates stale files and directories', () async {
    final subDirFrom = Directory(p.join(from.path, '1'));
    final subDirTo1 = Directory(p.join(to.path, '1'));
    final subDirTo2 = Directory(p.join(to.path, '2'));

    subDirFrom.createSync();
    subDirTo1.createSync();
    subDirTo2.createSync();

    final fileFrom = File(p.join(subDirFrom.path, 'a'));
    final fileTo1 = File(p.join(subDirTo1.path, 'a'));
    final fileTo2 = File(p.join(subDirTo2.path, 'b'));

    fileTo1.writeAsStringSync('contentsTo1');
    fileTo2.writeAsStringSync('contentsTo2');
    await Future.delayed(const Duration(seconds: 1));
    fileFrom.writeAsStringSync('contentsFrom');

    await updatePath(from.path, to.path);

    expect(fileTo1.readAsStringSync(), equals('contentsFrom'));
    expect(fileTo2.existsSync(), isFalse);
  });

  test('updatePath does not update newer files and directories', () async {
    final subDirFrom = Directory(p.join(from.path, '1'));
    final subDirTo1 = Directory(p.join(to.path, '1'));
    final subDirTo2 = Directory(p.join(to.path, '2'));

    subDirFrom.createSync();
    subDirTo1.createSync();
    subDirTo2.createSync();

    final fileFrom = File(p.join(subDirFrom.path, 'a'));
    final fileTo1 = File(p.join(subDirTo1.path, 'a'));
    final fileTo2 = File(p.join(subDirTo2.path, 'b'));

    fileFrom.writeAsStringSync('contentsFrom');
    await Future.delayed(const Duration(seconds: 1));
    fileTo1.writeAsStringSync('contentsTo1');
    fileTo2.writeAsStringSync('contentsTo2');

    await updatePath(from.path, to.path);

    expect(fileTo1.readAsStringSync(), equals('contentsTo1'));
    expect(fileTo2.existsSync(), isFalse);
  });
}
