// Copyright (c) 2013, 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.
//
// Dart test program for testing dart:io FileSystemEntity.Stat().

// @dart = 2.9

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

import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
import "package:path/path.dart";

void testStat() {
  Directory directory = Directory.systemTemp.createTempSync('dart_file_stat');
  File file = new File(join(directory.path, "file"));
  FileStat fileStat = FileStat.statSync(file.path);
  FileStat fileStatDirect = file.statSync();
  Expect.equals(FileSystemEntityType.notFound, fileStat.type);
  Expect.equals(FileSystemEntityType.notFound, fileStatDirect.type);
  file.writeAsStringSync("Dart IO library test of FileStat");
  Link link = new Link(join(directory.path, "link"));
  link.createSync(file.path);
  new Timer(const Duration(seconds: 2), () {
    file.readAsStringSync();
    directory.listSync();
    FileStat fileStat = FileStat.statSync(file.path);
    FileStat fileStatDirect = file.statSync();
    FileStat linkStat = FileStat.statSync(link.path);
    FileStat linkStatDirect = link.statSync();

    Expect.equals(FileSystemEntityType.file, fileStat.type);
    Expect.equals(32, fileStat.size);
    Expect.equals(FileSystemEntityType.file, fileStatDirect.type);
    Expect.equals(32, fileStatDirect.size);
    if (Platform.operatingSystem != 'windows') {
      Expect.isTrue(fileStat.modified.compareTo(fileStat.accessed) < 0);
      Expect.isTrue(fileStat.changed.compareTo(fileStat.accessed) < 0);
    }
    Expect.equals(6 << 6, fileStat.mode & (6 << 6)); // Mode includes +urw.
    FileStat directoryStat = FileStat.statSync(directory.path);
    FileStat directoryStatDirect = directory.statSync();
    Expect.equals(FileSystemEntityType.directory, directoryStat.type);
    Expect.equals(FileSystemEntityType.directory, directoryStatDirect.type);
    if (Platform.operatingSystem != 'windows') {
      Expect
          .isTrue(directoryStat.modified.compareTo(directoryStat.accessed) < 0);
      Expect
          .isTrue(directoryStat.changed.compareTo(directoryStat.accessed) < 0);
    }
    Expect.equals(7 << 6, directoryStat.mode & (7 << 6)); // Includes +urwx.

    // Verify that statSync resolves the link.
    Expect.equals(FileSystemEntityType.file, linkStat.type);
    Expect.equals(32, linkStat.size);
    Expect.equals(FileSystemEntityType.file, linkStatDirect.type);
    Expect.equals(32, linkStatDirect.size);

    directory.deleteSync(recursive: true);
  });
}

Future testStatAsync() {
  return Directory.systemTemp.createTemp('dart_file_stat').then((directory) {
    File file = new File(join(directory.path, "file"));
    return FileStat.stat(file.path)
        .then((fileStat) =>
            Expect.equals(FileSystemEntityType.notFound, fileStat.type))
        .then((_) => file.stat())
        .then((fileStat) =>
            Expect.equals(FileSystemEntityType.notFound, fileStat.type))
        .then((_) => file.writeAsString("Dart IO library test of FileStat"))
        .then((_) => new Future.delayed(const Duration(seconds: 2)))
        .then((_) => file.readAsString())
        .then((_) => directory.list().last)
        .then((_) => FileStat.stat(file.path))
        .then((FileStat fileStat) {
      Expect.equals(FileSystemEntityType.file, fileStat.type);
      Expect.equals(32, fileStat.size);
      if (Platform.operatingSystem != 'windows') {
        Expect.isTrue(fileStat.modified.compareTo(fileStat.accessed) < 0);
        Expect.isTrue(fileStat.changed.compareTo(fileStat.accessed) < 0);
      }
      Expect.equals(6 << 6, fileStat.mode & (6 << 6)); // Mode includes +urw.
      return file.stat();
    }).then((FileStat fileStat) {
      Expect.equals(FileSystemEntityType.file, fileStat.type);
      Expect.equals(32, fileStat.size);
      if (Platform.operatingSystem != 'windows') {
        Expect.isTrue(fileStat.modified.compareTo(fileStat.accessed) < 0);
        Expect.isTrue(fileStat.changed.compareTo(fileStat.accessed) < 0);
      }
      Expect.equals(6 << 6, fileStat.mode & (6 << 6)); // Mode includes +urw.
      return FileStat.stat(directory.path);
    }).then((FileStat directoryStat) {
      Expect.equals(FileSystemEntityType.directory, directoryStat.type);
      if (Platform.operatingSystem != 'windows') {
        Expect.isTrue(
            directoryStat.modified.compareTo(directoryStat.accessed) < 0);
        Expect.isTrue(
            directoryStat.changed.compareTo(directoryStat.accessed) < 0);
      }
      Expect.equals(7 << 6, directoryStat.mode & (7 << 6)); // Includes +urwx.
      return directory.stat();
    }).then((FileStat directoryStat) {
      Expect.equals(FileSystemEntityType.directory, directoryStat.type);
      if (Platform.operatingSystem != 'windows') {
        Expect.isTrue(
            directoryStat.modified.compareTo(directoryStat.accessed) < 0);
        Expect.isTrue(
            directoryStat.changed.compareTo(directoryStat.accessed) < 0);
      }
      Expect.equals(7 << 6, directoryStat.mode & (7 << 6)); // Includes +urwx.
      return new Link(directory.path).stat();
    }).then((FileStat linkStat) {
      Expect.equals(FileSystemEntityType.directory, linkStat.type);
      if (Platform.operatingSystem != 'windows') {
        Expect.isTrue(linkStat.modified.compareTo(linkStat.accessed) < 0);
        Expect.isTrue(linkStat.changed.compareTo(linkStat.accessed) < 0);
      }
      Expect.equals(7 << 6, linkStat.mode & (7 << 6)); // Includes +urwx.
      return directory.delete(recursive: true);
    });
  });
}

void main() {
  asyncStart();
  testStat();
  testStatAsync().then((_) => asyncEnd());
}
