#!/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.
"""Updates the python scripts in python/perfetto/prebuilts/manifests

This script does the following, for each entry in MANIFESTS_TO_UPDATE:
  - Downloads the artifact by the LUCI infrastructure, one for each arch.
  - Computes the SHA-256 of each artifact.
  - Generates a manifest with URL, SHA-256 and other details.
  - Merges get_perfetto_prebuilt.py with the manifest and writes tools/xxx.

This script is supposed to be run by Perfetto OWNERS after every monthly release
after the LUCI jobs have completed.
"""

import argparse
import hashlib
import logging
import os
import subprocess
import sys

from concurrent.futures import ThreadPoolExecutor

GCS_URL = 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts'

ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MANIFESTS_DIR = os.path.join(ROOT_DIR, 'python/perfetto/prebuilts/manifests')

UNIX_ARCHS = [
    'mac-amd64',
    'mac-arm64',
    'linux-amd64',
    'linux-arm',
    'linux-arm64',
    'android-arm',
    'android-arm64',
    'android-x86',
    'android-x64',
]
ALL_ARCHS = UNIX_ARCHS + ['windows-amd64']

MANIFESTS_TO_UPDATE = [
    {
        'tool': 'trace_processor_shell',
        'archs': ALL_ARCHS
    },
    {
        'tool': 'traceconv',
        'archs': ALL_ARCHS
    },
    {
        'tool': 'tracebox',
        'archs': UNIX_ARCHS
    },
]

# Maps a 'os-arch' string (were arch follows LUCI conventions) into
# corresponding tuples that match against python's platform / machine API
# (see get_perfetto_prebuilt.py for usage).
ARCH_TO_PYTHON = {
    'mac-amd64': {
        'platform': 'darwin',
        'machine': ['x86_64'],
    },
    'mac-arm64': {
        'platform': 'darwin',
        'machine': ['arm64'],
    },
    'windows-amd64': {
        'platform': 'win32',
        'machine': ['amd64'],
    },
    'linux-amd64': {
        'platform': 'linux',
        'machine': ['x86_64'],
    },
    'linux-arm': {
        'platform': 'linux',
        'machine': ['armv6l', 'armv7l', 'armv8l'],
    },
    'linux-arm64': {
        'platform': 'linux',
        'machine': ['aarch64'],
    },
}


def make_manifest(git_revision, tool, arch):
  ext = '.exe' if arch.startswith('windows') else ''
  file_name = tool + ext
  url = '%s/%s/%s/%s' % (GCS_URL, git_revision, arch, file_name)
  logging.info('Downloading %s', url)
  data = subprocess.check_output(['curl', '-fsL', '-o', '-', url])
  manifest = {
      'arch': arch,
      'file_name': file_name,
      'file_size': len(data),
      'url': url,
      'sha256': hashlib.sha256(data).hexdigest()
  }
  manifest.update(ARCH_TO_PYTHON.get(arch, {}))
  return manifest


def update_manifest(git_revision, tool_name, archs):
  with ThreadPoolExecutor(max_workers=8) as executor:
    manifests = list(
        executor.map(lambda arch: make_manifest(git_revision, tool_name, arch),
                     archs))
  out_file = os.path.join(MANIFESTS_DIR, tool_name + '.py')

  content = '# This file has been generated by: {script} {git_revision}\n'
  content += '{tool_uppercase}_MANIFEST = {manifests}\n'
  content = content.format(
      script=__file__,
      tool_uppercase=tool_name.upper(),
      git_revision=git_revision,
      manifests=str(manifests))

  with open(out_file + '.tmp', 'w') as f:
    f.write(content)
  subprocess.check_call(['yapf', '-i', out_file + '.tmp'])
  os.rename(out_file + '.tmp', out_file)
  os.chmod(out_file, 0o755)


def main():
  usage = '%s v20.0 | 0a1b2c3d\n\n' % __file__
  usage += 'To list available revisions run\n'
  usage += 'gsutil ls gs://perfetto-luci-artifacts/\n'
  usage += 'or visit https://chrome-infra-packages.appspot.com/p/perfetto\n'
  parser = argparse.ArgumentParser(usage=usage)
  parser.add_argument('version')
  args = parser.parse_args()

  git_revision = args.version
  for spec in MANIFESTS_TO_UPDATE:
    logging.info('Updating %s', spec['tool'])
    update_manifest(git_revision, spec['tool'], spec['archs'])


if __name__ == '__main__':
  logging.basicConfig(level=logging.INFO)
  sys.exit(main())
