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

// results.json and flaky.json parses.

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

/// The path to the gsutil script.
String gsutilPy;

/// Cloud storage location containing results.
const testResultsStoragePath = "gs://dart-test-results/builders";

/// Cloud storage location containing approved results.
const approvedResultsStoragePath =
    "gs://dart-test-results-approved-results/builders";

/// Runs gsutil with the provided [arguments] and returns the standard output.
/// Returns null if the requested URL didn't exist.
Future<String> runGsutil(List<String> arguments) async {
  final processResult = await Process.run(
      "python", [gsutilPy]..addAll(arguments),
      runInShell: Platform.isWindows);
  if (processResult.exitCode != 0) {
    if (processResult.exitCode == 1 &&
            processResult.stderr.contains("No URLs matched") ||
        processResult.stderr.contains("One or more URLs matched no objects")) {
      return null;
    }
    String error = "Failed to run: python $gsutilPy $arguments\n"
        "exitCode: ${processResult.exitCode}\n"
        "stdout:\n${processResult.stdout}\n"
        "stderr:\n${processResult.stderr}";
    if (processResult.exitCode == 1 &&
        processResult.stderr.contains("401 Anonymous caller")) {
      error =
          "\n\nYou need to authenticate by running:\npython $gsutilPy config\n";
    }
    throw new Exception(error);
  }
  return processResult.stdout;
}

/// Returns the contents of the provided cloud storage [path], or null if it
/// didn't exist.
Future<String> catGsutil(String path) => runGsutil(["cat", path]);

/// Returns the files and directories in the provided cloud storage [directory],
/// or null if it didn't exist.
Future<Iterable<String>> lsGsutil(String directory) async {
  final contents = await runGsutil(["ls", directory]);
  if (contents == null) {
    return null;
  }
  return LineSplitter.split(contents).map((String path) {
    final elements = path.split("/");
    if (elements[elements.length - 1].isEmpty) {
      return elements[elements.length - 2];
    } else {
      return elements[elements.length - 1];
    }
  });
}

/// Copies a file to or from cloud storage.
Future cpGsutil(String source, String destination) =>
    runGsutil(["cp", source, destination]);

/// Copies a directory recursively to or from cloud strorage.
Future cpRecursiveGsutil(String source, String destination) =>
    runGsutil(["-m", "cp", "-r", "-Z", source, destination]);

/// Lists the bots in cloud storage.
Future<Iterable<String>> listBots() => lsGsutil("$testResultsStoragePath");

/// Returns the cloud storage path for the [bot].
String botCloudPath(String bot) => "$testResultsStoragePath/$bot";

/// Returns the cloud storage path to the [build] on the [bot].
String buildCloudPath(String bot, String build) =>
    "${botCloudPath(bot)}/$build";

/// Returns the cloud storage path to the [file] inside the [bot]'s directory.
String fileCloudPath(String bot, String file) => "${botCloudPath(bot)}/$file";

/// Reads the contents of the [file] inside the [bot]'s cloud storage.
Future<String> readFile(String bot, String file) =>
    catGsutil(fileCloudPath(bot, file));

/// Returns the cloud storage path to the [file] inside the [build] on the
/// [bot].
String buildFileCloudPath(String bot, String build, String file) =>
    "${buildCloudPath(bot, build)}/$file";

/// Reads the contents of the [file] inside the [build] in the [bot]'s cloud
/// storage.
Future<String> readBuildFile(String bot, String build, String file) =>
    catGsutil(buildFileCloudPath(bot, build, file));

List<Map<String, dynamic>> parseResults(String contents) {
  return LineSplitter.split(contents)
      .map(jsonDecode)
      .toList()
      .cast<Map<String, dynamic>>();
}

Future<List<Map<String, dynamic>>> loadResults(String path) async {
  final results = <Map<String, dynamic>>[];
  final lines = new File(path)
      .openRead()
      .transform(utf8.decoder)
      .transform(new LineSplitter());
  await for (final line in lines) {
    final Map<String, dynamic> map = jsonDecode(line);
    results.add(map);
  }
  return results;
}

Map<String, Map<String, dynamic>> createResultsMap(
        List<Map<String, dynamic>> results) =>
    new Map<String, Map<String, dynamic>>.fromIterable(results,
        key: (dynamic result) =>
            "${result["configuration"]}:${result["name"]}");

Map<String, Map<String, dynamic>> parseResultsMap(String contents) =>
    createResultsMap(parseResults(contents));

Future<Map<String, Map<String, dynamic>>> loadResultsMap(String path) async =>
    createResultsMap(await loadResults(path));
