#!/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 json
import os
import pprint
import string
import subprocess
import tempfile

import gn_to_bp_utils

# 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 gn_to_bp.py.

cc_library_static {
    name: "libskia",
    cflags: [
        $cflags
    ],

    cppflags:[
        $cflags_cc
    ],

    export_include_dirs: [
        $export_includes
    ],

    local_include_dirs: [
        $local_includes
    ],

    srcs: [
        $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
            ],
            cflags: [
                // Clang seems to think new/malloc will only be 4-byte aligned
                // on x86 Android. We're pretty sure it's actually 8-byte
                // alignment. tests/OverAlignedTest.cpp has more information,
                // and should fail if we're wrong.
                "-Wno-over-aligned"
            ],
        },

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

    defaults: ["skia_deps",
               "skia_pgo",
    ],
}

// Build libskia with PGO by default.
// Location of PGO profile data is defined in build/soong/cc/pgo.go
// and is separate from skia.
// To turn it off, set ANDROID_PGO_NO_PROFILE_USE environment variable
// or set enable_profile_use property to false.
cc_defaults {
    name: "skia_pgo",
    pgo: {
        instrumentation: true,
        profile_file: "hwui/hwui.profdata",
        benchmarks: ["hwui", "skia"],
        enable_profile_use: true,
    },
}

// "defaults" property to disable profile use for Skia tools and benchmarks.
cc_defaults {
    name: "skia_pgo_no_profile_use",
    defaults: [
        "skia_pgo",
    ],
    pgo: {
        enable_profile_use: false,
    },
}

cc_defaults {
    name: "skia_deps",
    shared_libs: [
        "libEGL",
        "libGLESv2",
        "libdng_sdk",
        "libexpat",
        "libft2",
        "libheif",
        "libicui18n",
        "libicuuc",
        "libjpeg",
        "liblog",
        "libpiex",
        "libpng",
        "libvulkan",
        "libz",
        "libcutils",
        "libnativewindow",
    ],
    static_libs: [
        "libarect",
        "libsfntly",
        "libwebp-decode",
        "libwebp-encode",
    ],
    group_static_libs: true,
}

cc_defaults {
    name: "skia_tool_deps",
    defaults: [
        "skia_deps",
        "skia_pgo_no_profile_use"
    ],
    static_libs: [
        "libjsoncpp",
        "libskia",
    ],
    cflags: [
        "-Wno-implicit-fallthrough",
        "-Wno-unused-parameter",
        "-Wno-unused-variable",
    ],
}

cc_test {
    name: "skia_dm",

    defaults: [
        "skia_tool_deps"
    ],

    local_include_dirs: [
        $dm_includes
    ],

    srcs: [
        $dm_srcs
    ],

    shared_libs: [
        "libbinder",
        "libutils",
    ],
}

cc_test {
    name: "skia_nanobench",

    defaults: [
        "skia_tool_deps"
    ],

    local_include_dirs: [
        $nanobench_includes
    ],

    srcs: [
        $nanobench_srcs
    ],

    data: [
        "resources/*",
    ],
}''')

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

extra_userconfig_defines = [
]

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']['//:skia']['sources'])
cflags          = strip_slashes(js['targets']['//:skia']['cflags'])
cflags_cc       = strip_slashes(js['targets']['//:skia']['cflags_cc'])
local_includes  = strip_slashes(js['targets']['//:skia']['include_dirs'])
export_includes = strip_slashes(js['targets']['//:public']['include_dirs'])
defines      = [str(d) for d in js['targets']['//:skia']['defines']]
defines      += extra_userconfig_defines

dm_srcs         = strip_slashes(js['targets']['//:dm']['sources'])
dm_includes     = strip_slashes(js['targets']['//:dm']['include_dirs'])

nanobench_target = js['targets']['//:nanobench']
nanobench_srcs     = strip_slashes(nanobench_target['sources'])
nanobench_includes = strip_slashes(nanobench_target['include_dirs'])

gn_to_bp_utils.GrabDependentValues(js, '//:skia', 'sources', srcs, None)
gn_to_bp_utils.GrabDependentValues(js, '//:dm', 'sources', dm_srcs, 'skia')
gn_to_bp_utils.GrabDependentValues(js, '//:nanobench', 'sources',
                                   nanobench_srcs, 'skia')

# skcms is a little special, kind of a second-party library.
local_includes.add("third_party/skcms")
dm_includes   .add("third_party/skcms")

# need to manually include the vulkanmemoryallocator headers. If HWUI ever needs
# direct access to the allocator we need to add it to export_includes as well.
srcs.add("third_party/vulkanmemoryallocator/GrVulkanMemoryAllocator.cpp")
local_includes.add("third_party/vulkanmemoryallocator/")

# Android's build will choke if we list headers.
def strip_headers(sources):
  return {s for s in sources if not s.endswith('.h')}

srcs            = strip_headers(srcs)
dm_srcs         = strip_headers(dm_srcs)
nanobench_srcs  = strip_headers(nanobench_srcs)

cflags = gn_to_bp_utils.CleanupCFlags(cflags)
cflags_cc = gn_to_bp_utils.CleanupCCFlags(cflags_cc)

here = os.path.dirname(__file__)
defs = gn_to_bp_utils.GetArchSources(os.path.join(here, 'opts.gni'))

gn_to_bp_utils.WriteUserConfig('include/config/SkUserConfig.h', defines)

# 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)

# OK!  We have everything to fill in Android.bp...
with open('Android.bp', 'w') as f:
  print >>f, bp.substitute({
    'export_includes': bpfmt(8, export_includes),
    '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, strip_headers(defs['armv7'])),
    'arm_neon_srcs': bpfmt(20, strip_headers(defs['neon'])),
    'arm64_srcs':    bpfmt(16, strip_headers(defs['arm64'] +
                                             defs['crc32'])),
    'none_srcs':     bpfmt(16, strip_headers(defs['none'])),
    'x86_srcs':      bpfmt(16, strip_headers(defs['sse2'] +
                                             defs['ssse3'] +
                                             defs['sse41'] +
                                             defs['sse42'] +
                                             defs['avx'  ] +
                                             defs['hsw'  ])),

    'dm_includes'       : bpfmt(8, dm_includes),
    'dm_srcs'           : bpfmt(8, dm_srcs),

    'nanobench_includes'    : bpfmt(8, nanobench_includes),
    'nanobench_srcs'        : bpfmt(8, nanobench_srcs),
  })
