// 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.

// 'fuzz' test the file APIs by providing unexpected type arguments. The test
// passes if the VM does not crash.

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

import 'fuzz_support.dart';

import "package:async_helper/async_helper.dart";

fuzzSyncMethods() {
  var temp = Directory.systemTemp.createTempSync('dart_file_fuzz');
  typeMapping.forEach((k, v) {
    File? file;
    doItSync(() => file = new File('${temp.path}/${v as String}'));
    if (file == null) return;
    final f = file!;
    doItSync(f.existsSync);
    doItSync(f.createSync);
    doItSync(f.deleteSync);
    doItSync(f.lengthSync);
    doItSync(f.lastModifiedSync);
    doItSync(() => f.path);
    doItSync(() => f.openRead().listen((_) {}, onError: (e) {}));
    doItSync(f.readAsBytesSync);
    doItSync(f.readAsStringSync);
    doItSync(f.readAsLinesSync);
    typeMapping.forEach((k2, v2) {
      doItSync(() => f.openSync(mode: v2 as FileMode));
      doItSync(() => f.openWrite(mode: v2 as FileMode));
      doItSync(() => f.readAsStringSync(encoding: v2 as Encoding));
      doItSync(() => f.readAsLinesSync(encoding: v2 as Encoding));
    });
  });
  temp.deleteSync(recursive: true);
}

fuzzAsyncMethods() {
  asyncStart();
  var futures = <Future>[];
  var temp = Directory.systemTemp.createTempSync('dart_file_fuzz');
  typeMapping.forEach((k, v) {
    File? file;
    doItSync(() => file = new File('${temp.path}/${v as String}'));
    if (file == null) return;
    final f = file!;
    futures.add(doItAsync(f.exists));
    futures.add(doItAsync(f.delete));
    futures.add(doItAsync(() => f.parent));
    futures.add(doItAsync(f.length));
    futures.add(doItAsync(f.lastModified));
    futures.add(doItAsync(f.open));
    futures.add(doItAsync(() => f.path));
    futures.add(doItAsync(f.readAsBytes));
    futures.add(doItAsync(f.readAsLines));
    futures.add(doItAsync(f.readAsString));
    typeMapping.forEach((k2, v2) {
      futures.add(doItAsync(() => f.open(mode: v2 as FileMode)));
      futures.add(doItAsync(() => f.readAsString(encoding: v2 as Encoding)));
      futures.add(doItAsync(() => f.readAsLines(encoding: v2 as Encoding)));
    });
  });
  Future.wait(futures).then((_) {
    temp.deleteSync(recursive: true);
    asyncEnd();
  });
}

fuzzSyncRandomAccessMethods() {
  var temp = Directory.systemTemp.createTempSync('dart_file_fuzz');
  var file = new File('${temp.path}/x');
  file.createSync();
  var modes = [FileMode.read, FileMode.write, FileMode.append];
  for (var m in modes) {
    var opened = file.openSync(mode: m);
    typeMapping.forEach((k, v) {
      doItSync(() => opened.setPositionSync(v as int));
      doItSync(() => opened.truncateSync(v as int));
      doItSync(() => opened.writeByteSync(v as int));
    });
    for (var p in typePermutations(2)) {
      doItSync(() => opened.writeStringSync(p[0], encoding: p[1]));
    }
    for (var p in typePermutations(3)) {
      doItSync(() => opened.readIntoSync(p[0], p[1], p[2]));
      doItSync(() => opened.writeFromSync(p[0], p[1], p[2]));
    }
    opened.closeSync();
  }
  temp.deleteSync(recursive: true);
}

fuzzAsyncRandomAccessMethods() {
  var temp = Directory.systemTemp.createTempSync('dart_file_fuzz');
  var file = new File('${temp.path}/x');
  file.createSync();
  var modes = [FileMode.read, FileMode.write, FileMode.append];
  var futures = <Future>[];
  var openedFiles = [];
  for (var m in modes) {
    var opened = file.openSync(mode: m);
    openedFiles.add(opened);
    typeMapping.forEach((k, v) {
      futures.add(doItAsync(() => opened.setPosition(v as int)));
      futures.add(doItAsync(() => opened.truncate(v as int)));
      futures.add(doItAsync(() => opened.writeByte(v as int)));
    });
    for (var p in typePermutations(2)) {
      futures.add(doItAsync(() => opened.writeString(p[0], encoding: p[1])));
    }
    for (var p in typePermutations(3)) {
      futures.add(doItAsync(() => opened.readInto(p[0], p[1], p[2])));
      futures.add(doItAsync(() => opened.writeFrom(p[0], p[1], p[2])));
    }
  }
  Future.wait(futures).then((ignore) {
    for (var opened in openedFiles) {
      opened.closeSync();
    }
    temp.deleteSync(recursive: true);
  });
}

main() {
  fuzzSyncMethods();
  fuzzAsyncMethods();
  fuzzSyncRandomAccessMethods();
  fuzzAsyncRandomAccessMethods();
}
