#!/usr/bin/env python3
# Copyright (C) 2021 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
""" Builds all the revisions in channels.json and deploys them if --upload.

See go/perfetto-ui-autopush for docs on how this works end-to-end.
"""

import argparse
import json
import os
import re
import shutil
import subprocess
import sys

from os.path import dirname
pjoin = os.path.join

BUCKET_NAME = 'ui.perfetto.dev'
CUR_DIR = dirname(os.path.abspath(__file__))
ROOT_DIR = dirname(dirname(CUR_DIR))


def check_call_and_log(args):
  print(' '.join(args))
  subprocess.check_call(args)


def check_output(args):
  return subprocess.check_output(args).decode().strip()


def version_exists(version):
  url = 'https://commondatastorage.googleapis.com/%s/%s/manifest.json' % (
      BUCKET_NAME, version)
  return 0 == subprocess.call(['curl', '-fLs', '-o', '/dev/null', url])


def build_git_revision(channel, git_ref, tmp_dir):
  workdir = pjoin(tmp_dir, channel)
  check_call_and_log(['rm', '-rf', workdir])
  check_call_and_log(['git', 'clone', '--quiet', '--shared', ROOT_DIR, workdir])
  old_cwd = os.getcwd()
  os.chdir(workdir)
  try:
    check_call_and_log(['git', 'reset', '--hard', git_ref])
    check_call_and_log(['git', 'clean', '-dfx'])
    git_sha = check_output(['git', 'rev-parse', 'HEAD'])
    print('===================================================================')
    print('Building UI for channel %s @ %s (%s)' % (channel, git_ref, git_sha))
    print('===================================================================')
    version = check_output(['tools/write_version_header.py', '--stdout'])
    check_call_and_log(['tools/install-build-deps', '--ui'])
    check_call_and_log(['ui/build'])
    return version, pjoin(workdir, 'ui/out/dist')
  finally:
    os.chdir(old_cwd)


def build_all_channels(channels, tmp_dir, merged_dist_dir):
  channel_map = {}
  for chan in channels:
    channel = chan['name']
    git_ref = chan['rev']
    # version here is something like "v1.2.3".
    version, dist_dir = build_git_revision(channel, git_ref, tmp_dir)
    channel_map[channel] = version
    check_call_and_log(['cp', '-an', pjoin(dist_dir, version), merged_dist_dir])
    if channel != 'stable':
      continue
    # Copy also the /index.html and /service_worker.*, but only for the stable
    # channel. The /index.html and SW must be shared between all channels,
    # because they are all reachable through ui.perfetto.dev/. Both the index
    # and the SQ are supposed to be version-independent (go/perfetto-channels).
    # If an accidental incompatibility bug sneaks in, we should much rather
    # crash canary (or any other channel) rather than stable. Hence why we copy
    # the index+sw from the stable channel.
    for fname in os.listdir(dist_dir):
      fpath = pjoin(dist_dir, fname)
      if os.path.isfile(fpath):
        check_call_and_log(['cp', '-an', fpath, merged_dist_dir])
  return channel_map


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('--upload', action='store_true')
  parser.add_argument('--tmp', default='/tmp/perfetto_ui')
  args = parser.parse_args()

  # Read the releases.json, which maps channel names to git refs, e.g.:
  # {name:'stable', rev:'a0b1c2...0}, {name:'canary', rev:'HEAD'}
  channels = []
  with open(pjoin(CUR_DIR, 'channels.json')) as f:
    channels = json.load(f)['channels']

  merged_dist_dir = pjoin(args.tmp, 'dist')
  check_call_and_log(['rm', '-rf', merged_dist_dir])
  shutil.os.makedirs(merged_dist_dir)
  channel_map = build_all_channels(channels, args.tmp, merged_dist_dir)

  print('Updating index in ' + merged_dist_dir)
  with open(pjoin(merged_dist_dir, 'index.html'), 'r+') as f:
    index_html = f.read()
    f.seek(0, 0)
    f.truncate()
    index_html = re.sub(r"data-perfetto_version='[^']*'",
                        "data-perfetto_version='%s'" % json.dumps(channel_map),
                        index_html)
    f.write(index_html)

  if not args.upload:
    return

  print('===================================================================')
  print('Uploading to gs://%s' % BUCKET_NAME)
  print('===================================================================')
  cp_cmd = [
      'gsutil', '-m', '-h', 'Cache-Control:public, max-age=3600', 'cp', '-j',
      'html,js,css,wasm'
  ]
  for name in os.listdir(merged_dist_dir):
    path = pjoin(merged_dist_dir, name)
    if os.path.isdir(path):
      if version_exists(name):
        print('Skipping upload of %s because it already exists on GCS' % name)
        continue
      check_call_and_log(cp_cmd + ['-r', path, 'gs://%s/' % BUCKET_NAME])
    else:
      # /index.html or /service_worker.js{,.map}
      check_call_and_log(cp_cmd + [path, 'gs://%s/%s' % (BUCKET_NAME, name)])


if __name__ == '__main__':
  sys.exit(main())
