/*
 * Copyright (c) 2017, 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.
 */
/*
 * File and Directory utils
 * @author sgrekhov@unipro.ru
 */
library file_utils;

import "dart:io";
import "dart:async";
import "dart:math";
import "../../Utils/expect.dart";

final int eventsTimeout = 45;

Future<Object?> inSandbox(Object? test(Directory sandbox), {Directory? sandbox}) async {
  if (sandbox == null) {
    sandbox = getTempDirectorySync();
  }
  try {
    return await test(sandbox);
  } finally {
    sandbox.deleteSync(recursive: true);
  }
}

Future<void> testFileSystemEvent<T extends FileSystemEvent>(Directory root,
    {required Future<void> createEvent(),
    required void test(FileSystemEvent? event), bool failIfNoEvent = true,
    bool ignoreRootEvents = true}) async {
  final eventCompleter = new Completer<FileSystemEvent?>();
  bool first = true;
  StreamSubscription? subscription;
  subscription = root.watch().listen((FileSystemEvent event) async {
    if (!ignoreRootEvents || root.path != event.path) {
      if (event is T) {
        if (first) {
          first = false;
          eventCompleter.complete(event);
          await subscription?.cancel();
        }
      }
    }
  });
  await createEvent();
  final event = await eventCompleter.future
      .timeout(Duration(seconds: eventsTimeout), onTimeout: () async {
    await subscription?.cancel();
    if (failIfNoEvent) {
      Expect.fail("No event was fired for $eventsTimeout seconds");
    }
  });
  test(event);
}

/**
 * Creates temporary file in a parent directory
 */
File getTempFileSync({Directory? parent, String? name}) {
  parent ??= Directory.systemTemp;
  name ??= getPrefix() + getTempFileName();
  File file = new File(parent.path + Platform.pathSeparator + name);
  file.createSync();
  return file;
}

Future<File> getTempFile({Directory? parent, String? name}) async {
  parent ??= Directory.systemTemp;
  name ??= getPrefix() + getTempFileName();
  return new File(parent.path + Platform.pathSeparator + name).create();
}

Directory getTempDirectorySync({Directory? parent, String? name}) {
  parent ??= Directory.systemTemp;
  if (name == null) {
    return parent.createTempSync(getPrefix());
  }
  Directory dir = new Directory(parent.path + Platform.pathSeparator + name);
  dir.createSync();
  return dir;
}

Future<Directory> getTempDirectory({Directory? parent, String? name}) async {
  parent ??= Directory.systemTemp;
  if (name == null) {
    return parent.createTemp(getPrefix());
  }
  Directory dir = new Directory(parent.path + Platform.pathSeparator + name);
  return dir.create();
}

Link getTempLinkSync({Directory? parent, String? target, String? name}) {
  parent ??= Directory.systemTemp;
  target ??= getTempDirectorySync(parent: parent).path;
  name ??= getPrefix() + getTempFileName(extension: ".lnk");
  Link link = new Link(parent.path + Platform.pathSeparator + name);
  link.createSync(target);
  return link;
}

Future<Link> getTempLink({Directory? parent, String? target, String? name}) {
  parent ??= Directory.systemTemp;
  target ??= getTempDirectorySync(parent: parent).path;
  name ??= getPrefix() + getTempFileName();
  Link link = new Link(parent.path + Platform.pathSeparator + name);
  return link.create(target);
}

void deleteLinkWithTarget(Link link) {
  String linkTarget = link.targetSync();
  FileSystemEntity? target = null;
  if (FileSystemEntity.isDirectorySync(linkTarget)) {
    target = new Directory(linkTarget);
  } else if (FileSystemEntity.isFileSync(linkTarget)) {
    target = new File(linkTarget);
  } else if (FileSystemEntity.isLinkSync(linkTarget)) {
    target = new Link(linkTarget);
  }
  try {
    target?.delete(recursive: true);
  } on Exception {}
  try {
    link.delete();
  } on Exception {}
}

Random rnd = new Random(new DateTime.now().microsecondsSinceEpoch);

String getTempFileName({String? extension}) {
  extension = (extension == null
      ? ".tmp"
      : (extension.startsWith(".") ? extension : "." + extension));
  String name = rnd.nextInt(10000).toString() +
      "-" +
      rnd.nextInt(10000).toString() +
      "-" +
      rnd.nextInt(10000).toString() +
      "-" +
      rnd.nextInt(10000).toString() +
      extension;
  return name;
}

String getTempDirectoryName() {
  String name = rnd.nextInt(10000).toString() +
      "-" +
      rnd.nextInt(10000).toString() +
      "-" +
      rnd.nextInt(10000).toString() +
      "-" +
      rnd.nextInt(10000).toString();
  return name;
}

String getPrefix() {
  String fileName =
      Platform.script.pathSegments[Platform.script.pathSegments.length - 1];
  return "co19-" + fileName.substring(0, fileName.indexOf(".")) + "_";
}

String getTempFilePath({Directory? parent, String? name}) {
  parent ??= Directory.systemTemp;
  name ??= getPrefix() + getTempFileName();
  return parent.path + Platform.pathSeparator + name;
}

String getTempDirectoryPath({Directory? parent, String? name}) {
  parent ??= Directory.systemTemp;
  name ??= getTempDirectoryName();
  return parent.path + Platform.pathSeparator + name;
}

String getEntityName(FileSystemEntity entity) =>
    entity.path.substring(entity.path.lastIndexOf(Platform.pathSeparator) + 1);
