#!/usr/bin/env python
#
# Copyright 2016 Google Inc.
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Generate Android.bp for Skia from GN configuration.

import argparse
import json
import os
import pprint
import string
import subprocess
import sys
import tempfile

root_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                        os.pardir, os.pardir)
skia_gn_dir = os.path.join(root_dir, 'gn')
sys.path.insert(0, skia_gn_dir)

import gn_to_bp_utils

from skqp_gn_args import SkqpGnArgs

# First we start off with a template for Android.bp,
# with holes for source lists and include directories.
bp = string.Template('''// This file is autogenerated by tools/skqp/gn_to_bp.py.

cc_library_shared {
    name: "libskqp_app",
    sdk_version: "26",
    stl: "libc++_static",
    compile_multilib: "both",

    cflags: [
        $cflags
        "-Wno-unused-parameter",
        "-Wno-unused-variable",
    ],

    cppflags:[
        $cflags_cc
    ],

    local_include_dirs: [
        $local_includes
    ],

    srcs: [
        "third_party/vulkanmemoryallocator/GrVulkanMemoryAllocator.cpp",
        $srcs
    ],

    arch: {
        arm: {
            srcs: [
                $arm_srcs
            ],

            neon: {
                srcs: [
                    $arm_neon_srcs
                ],
            },
        },

        arm64: {
            srcs: [
                $arm64_srcs
            ],
        },

        mips: {
            srcs: [
                $none_srcs
            ],
        },

        mips64: {
            srcs: [
                $none_srcs
            ],
        },

        x86: {
            srcs: [
                $x86_srcs
            ],
        },

        x86_64: {
            srcs: [
                $x86_srcs
            ],
        },
    },

    shared_libs: [
          "libandroid",
          "libEGL",
          "libGLESv2",
          "liblog",
          "libvulkan",
          "libz",
    ],
    static_libs: [
          "libexpat",
          "libjpeg_static_ndk",
          "libpng_ndk",
          "libwebp-decode",
          "libwebp-encode",
    ]
}''')

# We'll run GN to get the main source lists and include directories for Skia.
gn_args = {
  'target_cpu': '"none"',
  'target_os':  '"android"',

  # setup skqp
  'is_debug':   'false',
  'ndk_api':    '26',

  # specify that the Android.bp will supply the necessary components
  'skia_use_system_expat':         'true', # removed this when gn is fixed
  'skia_use_system_libpng':        'true',
  'skia_use_system_libwebp':       'true',
  'skia_use_system_libjpeg_turbo': 'true',
  'skia_use_system_zlib':          'true',
}

for k, v in SkqpGnArgs.iteritems():
    gn_args[k] = v

js = gn_to_bp_utils.GenerateJSONFromGN(gn_args)

def strip_slashes(lst):
  return {str(p.lstrip('/')) for p in lst}

srcs            = strip_slashes(js['targets']['//:libskqp_app']['sources'])
cflags          = strip_slashes(js['targets']['//:libskqp_app']['cflags'])
cflags_cc       = strip_slashes(js['targets']['//:libskqp_app']['cflags_cc'])
local_includes  = strip_slashes(js['targets']['//:libskqp_app']['include_dirs'])
defines      = {str(d) for d in js['targets']['//:libskqp_app']['defines']}

defines.update(["SK_ENABLE_DUMP_GPU", "SK_BUILD_FOR_SKQP"])
cflags_cc.update(['-Wno-extra-semi-stmt'])

# Android does not want -Weverything set, it blocks toolchain updates.
assert '-Weverything' not in cflags

gn_to_bp_utils.GrabDependentValues(js, '//:libskqp_app', 'sources', srcs, None)
gn_to_bp_utils.GrabDependentValues(js, '//:libskqp_app', 'include_dirs',
                                   local_includes, 'freetype')
gn_to_bp_utils.GrabDependentValues(js, '//:libskqp_app', 'defines',
                                   defines, None)

# No need to list headers or other extra flags.
srcs = {s for s in srcs           if not s.endswith('.h')}
cflags = gn_to_bp_utils.CleanupCFlags(cflags)
cflags_cc = gn_to_bp_utils.CleanupCCFlags(cflags_cc)

# We need to add the include path to the vulkan defines and header file set in
# then skia_vulkan_header gn arg that is used for framework builds.
local_includes.add("platform_tools/android/vulkan")

# Get architecture specific source files
defs = gn_to_bp_utils.GetArchSources(os.path.join(skia_gn_dir, 'opts.gni'))

# Add source file until fix lands in
# https://skia-review.googlesource.com/c/skia/+/101820
srcs.add("src/ports/SkFontMgr_empty_factory.cpp")

# Turn a list of strings into the style bpfmt outputs.
def bpfmt(indent, lst, sort=True):
  if sort:
    lst = sorted(lst)
  return ('\n' + ' '*indent).join('"%s",' % v for v in lst)

# Most defines go into SkUserConfig.h, where they're seen by Skia and its users.
gn_to_bp_utils.WriteUserConfig('include/config/SkUserConfig.h', defines)

# OK!  We have everything to fill in Android.bp...
with open('Android.bp', 'w') as f:
  print >>f, bp.substitute({
    'local_includes': bpfmt(8, local_includes),
    'srcs':           bpfmt(8, srcs),
    'cflags':         bpfmt(8, cflags, False),
    'cflags_cc':      bpfmt(8, cflags_cc),

    'arm_srcs':       bpfmt(16, defs['armv7']),
    'arm_neon_srcs':  bpfmt(20, defs['neon']),
    'arm64_srcs':     bpfmt(16, defs['arm64'] +
                                defs['crc32']),
    'none_srcs':      bpfmt(16, defs['none']),
    'x86_srcs':       bpfmt(16, defs['sse2'] +
                                defs['ssse3'] +
                                defs['sse41'] +
                                defs['sse42'] +
                                defs['avx'] +
                                defs['hsw']),
  })

