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

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 = PathSet(root);

  /// Use a fixed [math.Random] with a constant seed to ensure the tests are
  /// deterministic.
  final math.Random random = 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, void Function(String) callback) {
    void recurse(String path, int 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 = [];

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

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

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

  final List<String> paths = [];

  @override
  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',
      ]);
    }
  }

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

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

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

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

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

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

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

  final List<String> paths = [];

  @override
  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);
  }

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

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