#!/usr/bin/env python3
# Copyright (c) 2019, 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.
#
"""Tool to automatically update the DartFuzzStats spreadsheet

Requires a one-time authentication step with a @google account.
"""
from __future__ import print_function
import pickle
import os.path
import subprocess
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

# This script may require a one time install of Google API libraries:
# pip3 install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']

# The ID and range of a spreadsheet.
SPREADSHEET_ID = '1nDoK-dCuEmf6yo55a303UClRd7AwjbzPkRr37ijWcC8'
RANGE_NAME = 'Sheet1!A3:H'

VERIFY_CURRENT_ROW_FORMULA = '=B:B-C:C-D:D-E:E-F:F'


def authenticate():
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)
    return build('sheets', 'v4', credentials=creds)


# Returns the next run ID based on the last run ID found in the fuzzing
# spreadsheet.
def get_next_run_id(sheet):
    result = sheet.values().get(
        spreadsheetId=SPREADSHEET_ID, range=RANGE_NAME).execute()
    values = result.get('values', [])
    return int(values[-1][0]) + 1


# Inserts a new entry into the fuzzing spreadsheet.
def add_new_fuzzing_entry(sheet, run, tests, success, rerun, skipped, timeout,
                          divergences):

    entry = [run, tests, success, skipped, timeout, divergences, rerun]
    print(
        'Adding entry for run %d. Tests: %d Successes: %d Skipped: %d Timeouts: %d, Divergences: %d Re-runs: %d'
        % tuple(entry))

    values = {'values': [entry + [VERIFY_CURRENT_ROW_FORMULA]]}
    sheet.values().append(
        spreadsheetId=SPREADSHEET_ID,
        range=RANGE_NAME,
        body=values,
        valueInputOption='USER_ENTERED').execute()


# Scrapes the fuzzing shards for fuzzing run statistics.
#
# Returns a list of statistics in the following order:
#
# - # of tests
# - # of successes
# - # of re-runs
# - # of skipped runs
# - # of timeouts
# - # of divergences
#
def get_run_statistic_summary(run):
    output = subprocess.check_output([
        'python3', 'collect_data.py', '--output-csv', '--type=sum',
        'https://ci.chromium.org/p/dart/builders/ci.sandbox/fuzz-linux/%d' % run
    ])
    return list(map(int, output.decode('UTF-8').rstrip().split(',')))


def main():
    service = authenticate()
    # Call the Sheets API
    sheet = service.spreadsheets()
    while True:
        try:
            next_id = get_next_run_id(sheet)
            summary = get_run_statistic_summary(next_id)
            add_new_fuzzing_entry(sheet, next_id, *summary)
        except:
            # get_run_statistic_summary exits with non-zero exit code if we're out
            # of runs to check.
            print('No more runs to process. Exiting.')
            break


if __name__ == '__main__':
    main()
