#!/usr/bin/env python
#
# Copyright 2017 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from __future__ import print_function

import collections
import multiprocessing
import optparse
import os
import platform
import re
import shutil
import subprocess
import sys


SCRIPTS_DIR = os.path.abspath(os.path.dirname(__file__))
FFMPEG_DIR = os.path.abspath(os.path.join(SCRIPTS_DIR, '..', '..'))


# These profiles select different levels of format support. The 'default'
# profile includes only a few unencumbered formats, essentially those supported
# by Chromium. The 'max' profile includes most of the formats that ffmpeg
# supports. Some formats (e.g. Opus) aren't included, because more development
# is required to support them.
PROFILES = [
    'default',
    'max',
]


USAGE = """Usage: %prog [x64|arm64] [options] -- [configure_args]

Resulting binaries will be placed in:
  build.[x64|arm64]/default/out/
  build.[x64|arm64]/max/out/
  """


def PrintAndCheckCall(argv, *args, **kwargs):
  print('Running %s' % '\n '.join(argv))
  subprocess.check_call(argv, *args, **kwargs)


def GetDsoName(dso_name, dso_version):
  return 'lib%s.so.%s' % (dso_name, dso_version)


def RewriteFile(path, search, replace):
  with open(path) as f:
    contents = f.read()
  with open(path, 'w') as f:
    f.write(re.sub(search, replace, contents))


def BuildFFmpeg(target_arch, parallel_jobs, config_only, profile,
                configure_flags):
  config_dir = 'build.%s/%s' % (target_arch, profile)
  shutil.rmtree(config_dir, ignore_errors=True)
  os.makedirs(os.path.join(config_dir, 'out'))

  PrintAndCheckCall(
      [os.path.join(FFMPEG_DIR, 'configure')] + configure_flags, cwd=config_dir)

  RewriteFile(
      os.path.join(config_dir, 'config.h'),
      r'(#define HAVE_SYSCTL [01])',
      (r'#define HAVE_SYSCTL 0'))

  RewriteFile(
      os.path.join(config_dir, 'config.h'),
      r'(#define HAVE_AS_FUNC [01])',
      (r'#define HAVE_AS_FUNC 0'))

  RewriteFile(
      os.path.join(config_dir, 'config.h'),
      r'(#define HAVE_VALGRIND_VALGRIND_H [01])',
      (r'#define HAVE_VALGRIND_VALGRIND_H 0'))

  if config_only:
    print('Skipping build step as requested.')
  else:
    libraries = [
        os.path.join('libavcodec', GetDsoName('avcodec', 58)),
        os.path.join('libavformat', GetDsoName('avformat', 58)),
        os.path.join('libavutil', GetDsoName('avutil', 56)),
    ]
    PrintAndCheckCall(
        ['make', '-j%d' % parallel_jobs] + libraries, cwd=config_dir)
    for lib in libraries:
      shutil.copy(os.path.join(config_dir, lib),
                  os.path.join(config_dir, 'out'))

  if target_arch in ('arm64'):
    RewriteFile(
        os.path.join(config_dir, 'config.h'),
        r'(#define HAVE_VFP_ARGS [01])',
        (r'/* \1 -- softfp/hardfp selection is done by the fuchsia build */'))


def main(argv):
  parser = optparse.OptionParser(usage=USAGE)
  parser.add_option('--profile', action='append', dest='profiles',
                    choices=PROFILES,
                    help='Profile to build; determines e.g. supported codecs')
  parser.add_option('--config-only', action='store_true',
                    help='Skip the build step.')
  options, args = parser.parse_args(argv)

  if len(args) == 0:
    parser.print_help()
    return 1

  target_arch = args[0]
  configure_args = args[1:]

  parallel_jobs = multiprocessing.cpu_count()

  print('System information:\n'
        'Target arch   : %s\n'
        'Parallel jobs : %d\n' % (target_arch, parallel_jobs))

  configure_flags = collections.defaultdict(list)

  # Common configuration.  Note: --disable-everything does not in fact disable
  # everything, just non-library components such as decoders and demuxers.
  #TODO(dalesat): Consider --enable-libopus, --enable-decoder=libopus
  configure_flags['Common'].extend([
      '--disable-everything',
      '--disable-all',
      '--disable-doc',
      '--disable-htmlpages',
      '--disable-manpages',
      '--disable-podpages',
      '--disable-txtpages',
      '--disable-static',
      '--enable-avcodec',
      '--enable-avformat',
      '--enable-avutil',
      '--enable-fft',
      '--enable-rdft',
      '--enable-static',

      # Disable features.
      '--disable-debug',
      '--disable-bzlib',
      '--disable-iconv',
      '--disable-lzo',
      '--disable-network',
      '--disable-schannel',
      '--disable-sdl2',
      '--disable-symver',
      '--disable-xlib',
      '--disable-zlib',
      '--disable-securetransport',
      '--disable-faan',
      '--disable-alsa',

      # Disable automatically detected external libraries. This prevents
      # automatic inclusion of things like hardware decoders. Each roll should
      # audit new [autodetect] configure options and add any desired options to
      # this file.
      '--disable-autodetect',

      # Common codecs.
      '--enable-decoder=vorbis,flac',
      '--enable-decoder=pcm_u8,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,mp3',
      '--enable-decoder=pcm_s16be,pcm_s24be,pcm_mulaw,pcm_alaw',
      '--enable-decoder=theora,vp8,sbc,aptx',
      '--enable-demuxer=ogg,matroska,wav,flac,mp3,mov',
      '--enable-parser=opus,vorbis,flac,mpegaudio',
      '--enable-parser=vp3,vp8',
      '--enable-encoder=sbc',

      '--optflags="-O2"',
      '--enable-pic',

      # Force usage of yasm
      '--x86asmexe=yasm',
  ])

  configure_flags['Common'].extend([
      '--enable-pic',
      '--enable-lto',
      '--cc=clang',
      '--cxx=clang++',
      '--ld=clang',
  ])


  # TODO(dalesat): enable vp9 on arm64

  if target_arch == 'x64':
    configure_flags['Common'].extend([
        '--enable-decoder=vp9',
        '--enable-parser=vp9',
        '--sysroot=' + os.path.join(
            FFMPEG_DIR, '..', '..', 'build', 'third_party', 'sysroot', 'linux-x64'),
    ])
  elif target_arch == 'arm64':
    configure_flags['Common'].extend([
        '--enable-cross-compile',
        '--cross-prefix=/usr/bin/aarch64-linux-gnu-',
        '--target-os=linux',
        '--arch=aarch64',
        '--enable-armv8',
        '--extra-cflags=-march=armv8-a',
        '--sysroot=' + os.path.join(
            FFMPEG_DIR, '..', '..', 'build', 'third_party', 'sysroot', 'linux-arm64'),
        '--extra-cflags=--target=aarch64-linux-gnu',
        '--extra-ldflags=--target=aarch64-linux-gnu',
        '--disable-linux-perf',
    ])
  else:
    print('Error: Unknown target arch %r!' % (target_arch), file=sys.stderr)
    return 1

  configure_flags['default'].extend([
      # max enables MPEG4 which requires error resilience :(
      '--disable-error-resilience',
  ])

  configure_flags['max'].extend([
      '--enable-decoder=aac,h264,mp3',
      '--enable-demuxer=aac,mp3,mov',
      '--enable-parser=aac,h264,mpegaudio',
      # Enable playing avi files.
      '--enable-decoder=mpeg4',
      '--enable-parser=h263,mpeg4video',
      '--enable-demuxer=avi',
      # Enable playing Android 3gp files.
      '--enable-demuxer=amr',
      '--enable-decoder=amrnb,amrwb',
      # Wav files for playing phone messages.
      '--enable-decoder=gsm_ms',
      '--enable-demuxer=gsm',
      '--enable-parser=gsm',
  ])

  def do_build_ffmpeg(profile, configure_flags):
    if options.profiles and profile not in options.profiles:
      print('%s skipped' % profile)
      return

    print('%s configure/build:' % profile)
    BuildFFmpeg(target_arch, parallel_jobs,
                options.config_only, profile, configure_flags)

  do_build_ffmpeg('default',
                  configure_flags['Common'] +
                  configure_flags['default'] +
                  configure_args)
  do_build_ffmpeg('max',
                  configure_flags['Common'] +
                  configure_flags['max'] +
                  configure_args)

  print('Done. If desired you may copy config.h/config.asm into the '
        'source/config tree using copy_config.sh.')
  return 0


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
