// Copyright (c) 2021, 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 file I/O.

// OtherResources=fixed_length_file
// OtherResources=read_as_text.dat

import 'dart:async';
import 'dart:convert';
import 'dart:collection';
import 'dart:io';

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

class FileTest {
  static Directory? tempDirectory;
  static int numLiveAsyncTests = 0;

  static void asyncTestStarted() {
    asyncStart();
    ++numLiveAsyncTests;
  }

  static void asyncTestDone(String name) {
    asyncEnd();
    --numLiveAsyncTests;
    if (numLiveAsyncTests == 0) {
      deleteTempDirectory();
    }
  }

  static void createTempDirectory(Function doNext) {
    Directory.systemTemp.createTemp('dart_file').then((temp) {
      tempDirectory = temp;
      doNext();
    });
  }

  static void deleteTempDirectory() {
    tempDirectory!.deleteSync(recursive: true);
  }

  static testReadInto() async {
    asyncTestStarted();
    File file = new File(tempDirectory!.path + "/out_read_into");

    var openedFile = await file.open(mode: FileMode.write);
    await openedFile.writeFrom(const [1, 2, 3]);

    await openedFile.setPosition(0);
    var list = <int>[1, 2, 3];
    Expect.equals(3, await openedFile.readInto(list));
    Expect.listEquals([1, 2, 3], list);

    read(start, end, length, expected) async {
      var list = <int>[1, 2, 3];
      await openedFile.setPosition(0);
      Expect.equals(length, await openedFile.readInto(list, start, end));
      Expect.listEquals(expected, list);
      return list;
    }

    await read(0, 3, 3, [1, 2, 3]);
    await read(0, 2, 2, [1, 2, null]);
    await read(1, 2, 1, [null, 1, null]);
    await read(1, 3, 2, [null, 1, 2]);
    await read(2, 3, 1, [null, null, 1]);
    await read(0, 0, 0, [null, null, null]);

    await openedFile.close();

    asyncTestDone("testReadInto");
  }

  static void testReadAsText() {
    asyncTestStarted();
    var name = getFilename("fixed_length_file");
    var f = new File(name);
    f.readAsString(encoding: utf8).then((text) {
      Expect.isTrue(text.endsWith("42 bytes."));
      Expect.equals(42, text.length);
      var name = getFilename("read_as_text.dat");
      var f = new File(name);
      f.readAsString(encoding: utf8).then((text) {
        Expect.equals(6, text.length);
        var expected = [955, 120, 46, 32, 120, 10];
        Expect.listEquals(expected, text.codeUnits);
        f.readAsString(encoding: latin1).then((text) {
          Expect.equals(7, text.length);
          var expected = [206, 187, 120, 46, 32, 120, 10];
          Expect.listEquals(expected, text.codeUnits);
          var readAsStringFuture = f.readAsString(encoding: ascii);
          readAsStringFuture
              .then((text) {
                Expect.fail("Non-ascii char should cause error");
              })
              .catchError((e) {
                asyncTestDone("testReadAsText");
              });
        });
      });
    });
  }

  static String getFilename(String path) {
    return Platform.script.resolve(path).toFilePath();
  }

  // Main test entrypoint.
  // This test results in an unhandled exception in the isolate while
  // some async file IO operations are still pending. The unhandled
  // exception results in the 'File' object being leaked, the error
  // only shows up in the ASAN bots which detect the leak.
  static testMain() {
    asyncStart();
    var outerZone = Zone.current;
    var firstZone = Zone.current.fork(
      specification: ZoneSpecification(
        handleUncaughtError: (self, parent, zone, error, stacktrace) {
          asyncEnd();
          print("unittest-suite-success"); // For the test harness.
          exit(0);
        },
      ),
    );
    firstZone.run(() async {
      Expect.identical(firstZone, Zone.current);
      createTempDirectory(() {
        testReadAsText();
        testReadInto();
        Expect.equals(1, 0); // Should not execute this.
        asyncEnd();
      });
    });
  }
}

main() {
  FileTest.testMain();
}
