# Copyright 2019 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 argparse
import filecmp
import json
import logging
from logging import handlers
import os
import posixpath
import shutil
import subprocess

from core.external_modules import pandas as pd
from core.external_modules import numpy as np
from core import gsutil
from py_utils import tempfile_ext


PINBOARD_DIR = os.path.abspath(os.path.dirname(__file__))
TOOLS_PERF_DIR = os.path.normpath(os.path.join(PINBOARD_DIR, '..', '..'))
CACHED_DATA_DIR = os.path.join(TOOLS_PERF_DIR, '_cached_data', 'pinboard')

PINPOINT_CLI = os.path.join(TOOLS_PERF_DIR, 'pinpoint_cli')
JOB_CONFIGS_PATH = os.path.join(PINBOARD_DIR, 'job_configs.json')

JOBS_STATE_FILE = 'jobs_state.json'
DATASET_PKL_FILE = 'dataset.pkl'
DATASET_CSV_FILE = 'dataset.csv'

CLOUD_STORAGE_DIR = 'gs://chrome-health-tvdata/pinboard'
TZ = 'America/Los_Angeles'  # MTV-time.


# Only these are exported and uploaded to the Cloud Storage dataset.
MEASUREMENTS = set([
    # V8 metrics.
    'JavaScript:duration',
    'Optimize-Background:duration',
    'Optimize:duration',
    'RunsPerMinute',
    'Total-Main-Thread:duration',
    'Total:duration',
    'V8-Only-Main-Thread:duration',
    'V8-Only:duration',
    'memory:chrome:renderer_processes:reported_by_chrome:v8:effective_size',
    'total:500ms_window:renderer_eqt:v8',

    # Startup metrics.
    'experimental_content_start_time',
    'experimental_navigation_start_time',
    'first_contentful_paint_time',
    'messageloop_start_time',
    'navigation_commit_time',
])

# Compute averages over a fixed set of active stories. These may need to be
# periodically updated.
ACTIVE_STORIES = set([
    # v8.browsing_mobile.
    'browse:chrome:newtab:2019',
    'browse:chrome:omnibox:2019',
    'browse:media:facebook_photos:2019',
    'browse:media:flickr_infinite_scroll:2019',
    'browse:media:googleplaystore:2019',
    'browse:media:imgur:2019',
    'browse:media:youtube:2019',
    'browse:news:cricbuzz:2019',
    'browse:news:globo:2019',
    'browse:news:nytimes:2019',
    'browse:news:qq:2019',
    'browse:news:reddit:2019',
    'browse:news:toi:2019',
    'browse:shopping:amazon:2019',
    'browse:news:washingtonpost:2019',
    'browse:search:amp:sxg:2019',
    'browse:shopping:amazon:2019',
    'browse:shopping:avito:2019',
    'browse:shopping:flipkart:2019',
    'browse:shopping:lazada:2019',
    'browse:social:facebook:2019',
    'browse:social:instagram:2019',
    'browse:social:twitter:2019',
    'browse:tools:maps:2019',

    # v8.browsing_desktop.
    'browse:news:nytimes:2018',
    'browse:news:flipboard:2018',
    'browse:social:facebook_infinite_scroll:2018',
    'browse:tools:sheets:2019',
    'browse:media:tumblr:2018',
    'browse:tools:maps:2019',
    'browse:social:twitter_infinite_scroll:2018',
    'browse:tech:discourse_infinite_scroll:2018',
    'browse:social:twitter:2018',
    'browse:social:tumblr_infinite_scroll:2018',
    'browse:media:googleplaystore:2018',
    'browse:search:google:2018',
    'browse:news:cnn:2018',
    'browse:news:reddit:2018',
    'browse:search:google_india:2018',
    'browse:media:youtubetv:2019',

    # Speedometer2.
    'Speedometer2',
])


def StartPinpointJobs(state, date):
  """Start new pinpoint jobs for the last commit on the given date."""
  revision, timestamp = GetLastCommitOfDate(date)
  if any(item['revision'] == revision for item in state):
    logging.info('No new jobs to start.')
    return

  # Add a new item to the state with info about jobs for this revision.
  logging.info('Starting jobs for %s (%s):', timestamp[:10], revision)
  item = {'revision': revision, 'timestamp': timestamp, 'jobs': []}
  configs = LoadJsonFile(JOB_CONFIGS_PATH)
  for config in configs:
    config['base_git_hash'] = revision
    with tempfile_ext.NamedTemporaryFile() as tmp:
      json.dump(config, tmp)
      tmp.close()
      output = subprocess.check_output(
          ['vpython', PINPOINT_CLI, 'start-job', tmp.name],
          universal_newlines=True).strip()
    logging.info(output)