// Copyright (c) 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;

import '../framework/benchmarks.dart';
import '../framework/framework.dart';
import '../framework/utils.dart';

TaskFunction createAnalyzerCliTest({
  @required String sdk,
  @required String commit,
  @required DateTime timestamp,
}) {
  return new AnalyzerCliTask(sdk, commit, timestamp);
}

TaskFunction createAnalyzerServerTest({
  @required String sdk,
  @required String commit,
  @required DateTime timestamp,
}) {
  return new AnalyzerServerTask(sdk, commit, timestamp);
}

abstract class AnalyzerTask {
  Benchmark benchmark;

  Future<TaskResult> call() async {
    section(benchmark.name);
    await runBenchmark(benchmark, iterations: 3, warmUpBenchmark: true);
    return benchmark.bestResult;
  }
}

class AnalyzerCliTask extends AnalyzerTask {
  AnalyzerCliTask(String sdk, String commit, DateTime timestamp) {
    this.benchmark = new FlutterAnalyzeBenchmark(sdk, commit, timestamp);
  }
}

class AnalyzerServerTask extends AnalyzerTask {
  AnalyzerServerTask(String sdk, String commit, DateTime timestamp) {
    this.benchmark = new FlutterAnalyzeAppBenchmark(sdk, commit, timestamp);
  }
}

class FlutterAnalyzeBenchmark extends Benchmark {
  FlutterAnalyzeBenchmark(this.sdk, this.commit, this.timestamp)
      : super('flutter analyze --flutter-repo');

  final String sdk;
  final String commit;
  final DateTime timestamp;

  File get benchmarkFile =>
      file(path.join(flutterDirectory.path, 'analysis_benchmark.json'));

  @override
  TaskResult get lastResult => new TaskResult.successFromFile(benchmarkFile);

  @override
  Future<num> run() async {
    rm(benchmarkFile);
    await inDirectory(flutterDirectory, () async {
      await flutter('analyze', options: <String>[
        '--flutter-repo',
        '--benchmark',
      ]);
    });
    return addBuildInfo(benchmarkFile,
        timestamp: timestamp, expected: 25.0, sdk: sdk, commit: commit);
  }
}

class FlutterAnalyzeAppBenchmark extends Benchmark {
  FlutterAnalyzeAppBenchmark(this.sdk, this.commit, this.timestamp)
      : super('analysis server mega_gallery');

  final String sdk;
  final String commit;
  final DateTime timestamp;

  @override
  TaskResult get lastResult => new TaskResult.successFromFile(benchmarkFile);

  Directory get megaDir => dir(
      path.join(flutterDirectory.path, 'dev/benchmarks/mega_gallery'));
  File get benchmarkFile =>
      file(path.join(megaDir.path, 'analysis_benchmark.json'));

  @override
  Future<Null> init() {
    return inDirectory(flutterDirectory, () async {
      await dart(<String>['dev/tools/mega_gallery.dart']);
    });
  }

  @override
  Future<num> run() async {
    rm(benchmarkFile);
    await inDirectory(megaDir, () async {
      await flutter('analyze', options: <String>[
        '--watch',
        '--benchmark',
      ]);
    });
    return addBuildInfo(benchmarkFile,
        timestamp: timestamp, expected: 10.0, sdk: sdk, commit: commit);
  }
}
