// 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);
  });
}
