// Copyright (c) 2015, 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.

/// Benchmarks for the PathSet class.
library watcher.benchmark.path_set;

import 'dart:io';
import 'dart:math' as math;

import 'package:benchmark_harness/benchmark_harness.dart';
import 'package:path/path.dart' as p;

import 'package:watcher/src/path_set.dart';

final String root = Platform.isWindows ? r"C:\root" : "/root";

/// Base class for benchmarks on [PathSet].
abstract class PathSetBenchmark extends BenchmarkBase {
  PathSetBenchmark(String method) : super("PathSet.$method");

  final PathSet pathSet = new PathSet(root);

  /// Use a fixed [Random] with a constant seed to ensure the tests are
  /// deterministic.
  final math.Random random = new math.Random(1234);

  /// Walks over a virtual directory [depth] levels deep invoking [callback]
  /// for each "file".
  ///
  /// Each virtual directory contains ten entries: either subdirectories or
  /// files.
  void walkTree(int depth, callback(String path)) {
    recurse(path, remainingDepth) {
      for (var i = 0; i < 10; i++) {
        var padded = i.toString().padLeft(2, '0');
        if (remainingDepth == 0) {
          callback(p.join(path, "file_$padded.txt"));
        } else {
          var subdir = p.join(path, "subdirectory_$padded");
          recurse(subdir, remainingDepth - 1);
        }
      }
    }

    recurse(root, depth);
  }
}

class AddBenchmark extends PathSetBenchmark {
  AddBenchmark() : super("add()");

  final List<String> paths = [];

  void setup() {
    // Make a bunch of paths in about the same order we expect to get them from
    // Directory.list().
    walkTree(3, paths.add);
  }

  void run() {
    for (var path in paths) pathSet.add(path);
  }
}

class ContainsBenchmark extends PathSetBenchmark {
  ContainsBenchmark() : super("contains()");

  final List<String> paths = [];

  void setup() {
    // Add a bunch of paths to the set.
    walkTree(3, (path) {
      pathSet.add(path);
      paths.add(path);
    });

    // Add some non-existent paths to test the false case.
    for (var i = 0; i < 100; i++) {
      paths.addAll([
        "/nope",
        "/root/nope",
        "/root/subdirectory_04/nope",
        "/root/subdirectory_04/subdirectory_04/nope",
        "/root/subdirectory_04/subdirectory_04/subdirectory_04/nope",
        "/root/subdirectory_04/subdirectory_04/subdirectory_04/nope/file_04.txt",
      ]);
    }
  }

  void run() {
    var contained = 0;
    for (var path in paths) {
      if (pathSet.contains(path)) contained++;
    }

    if (contained != 10000) throw "Wrong result: $contained";
  }
}

class PathsBenchmark extends PathSetBenchmark {
  PathsBenchmark() : super("toSet()");

  void setup() {
    walkTree(3, pathSet.add);
  }

  void run() {
    var count = 0;
    for (var _ in pathSet.paths) {
      count++;
    }

    if (count != 10000) throw "Wrong result: $count";
  }
}

class RemoveBenchmark extends PathSetBenchmark {
  RemoveBenchmark() : super("remove()");

  final List<String> paths = [];

  void setup() {
    // Make a bunch of paths. Do this here so that we don't spend benchmarked
    // time synthesizing paths.
    walkTree(3, (path) {
      pathSet.add(path);
      paths.add(path);
    });

    // Shuffle the paths so that we delete them in a random order that
    // hopefully mimics real-world file system usage. Do the shuffling here so
    // that we don't spend benchmarked time shuffling.
    paths.shuffle(random);
  }

  void run() {
    for (var path in paths) pathSet.remove(path);
  }
}

main() {
  new AddBenchmark().report();
  new ContainsBenchmark().report();
  new PathsBenchmark().report();
  new RemoveBenchmark().report();
}
