#!/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=os.path.relpath(__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())
