// Copyright 2017 Google Inc. All rights reserved.
//
// 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.

package cc

import (
	"strings"

	"android/soong/android"
)

var (
	vndkSuffix     = ".vndk."
	binder32Suffix = ".binder32"
)

// Creates vndk prebuilts that include the VNDK version.
//
// Example:
//
//	vndk_prebuilt_shared {
//	    name: "libfoo",
//	    version: "27",
//	    target_arch: "arm64",
//	    vendor_available: true,
//	    product_available: true,
//	    vndk: {
//	        enabled: true,
//	    },
//	    export_include_dirs: ["include/external/libfoo/vndk_include"],
//	    arch: {
//	        arm64: {
//	            srcs: ["arm/lib64/libfoo.so"],
//	        },
//	        arm: {
//	            srcs: ["arm/lib/libfoo.so"],
//	        },
//	    },
//	}
type vndkPrebuiltProperties struct {
	VndkProperties

	// VNDK snapshot version.
	Version *string

	// Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64')
	Target_arch *string

	// If the prebuilt snapshot lib is built with 32 bit binder, this must be set to true.
	// The lib with 64 bit binder does not need to set this property.
	Binder32bit *bool

	// Prebuilt files for each arch.
	Srcs []string `android:"arch_variant"`

	// list of flags that will be used for any module that links against this module.
	Export_flags []string `android:"arch_variant"`

	// Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined symbols,
	// etc).
	Check_elf_files *bool
}

type vndkPrebuiltLibraryDecorator struct {
	*libraryDecorator
	properties      vndkPrebuiltProperties
	androidMkSuffix string
}

func (p *vndkPrebuiltLibraryDecorator) Name(name string) string {
	return name + p.NameSuffix()
}

func (p *vndkPrebuiltLibraryDecorator) NameSuffix() string {
	suffix := p.Version()
	if p.arch() != "" {
		suffix += "." + p.arch()
	}
	if Bool(p.properties.Binder32bit) {
		suffix += binder32Suffix
	}
	return vndkSuffix + suffix
}

func (p *vndkPrebuiltLibraryDecorator) Version() string {
	return String(p.properties.Version)
}

func (p *vndkPrebuiltLibraryDecorator) arch() string {
	return String(p.properties.Target_arch)
}

func (p *vndkPrebuiltLibraryDecorator) binderBit() string {
	if Bool(p.properties.Binder32bit) {
		return "32"
	}
	return "64"
}

func (p *vndkPrebuiltLibraryDecorator) SnapshotAndroidMkSuffix() string {
	return ".vendor"
}

func (p *vndkPrebuiltLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
	p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix())
	return p.libraryDecorator.linkerFlags(ctx, flags)
}

func (p *vndkPrebuiltLibraryDecorator) singleSourcePath(ctx ModuleContext) android.Path {
	if len(p.properties.Srcs) == 0 {
		ctx.PropertyErrorf("srcs", "missing prebuilt source file")
		return nil
	}

	if len(p.properties.Srcs) > 1 {
		ctx.PropertyErrorf("srcs", "multiple prebuilt source files")
		return nil
	}

	return android.PathForModuleSrc(ctx, p.properties.Srcs[0])
}

func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
	flags Flags, deps PathDeps, objs Objects) android.Path {
	if !p.MatchesWithDevice(ctx.DeviceConfig()) {
		ctx.Module().HideFromMake()
		return nil
	}

	if len(p.properties.Srcs) > 0 && p.shared() {
		p.libraryDecorator.exportIncludes(ctx)
		p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
		// current VNDK prebuilts are only shared libs.

		in := p.singleSourcePath(ctx)
		p.unstrippedOutputFile = in
		libName := in.Base()
		if p.stripper.NeedsStrip(ctx) {
			stripFlags := flagsToStripFlags(flags)
			stripped := android.PathForModuleOut(ctx, "stripped", libName)
			p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, stripFlags)
			in = stripped
		}

		// Optimize out relinking against shared libraries whose interface hasn't changed by
		// depending on a table of contents file instead of the library itself.
		tocFile := android.PathForModuleOut(ctx, libName+".toc")
		p.tocFile = android.OptionalPathForPath(tocFile)
		TransformSharedObjectToToc(ctx, in, tocFile)

		p.androidMkSuffix = p.NameSuffix()

		android.SetProvider(ctx, SharedLibraryInfoProvider, SharedLibraryInfo{
			SharedLibrary: in,
			Target:        ctx.Target(),

			TableOfContents: p.tocFile,
		})

		p.libraryDecorator.flagExporter.setProvider(ctx)

		return in
	}

	ctx.Module().HideFromMake()
	return nil
}

func (p *vndkPrebuiltLibraryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) {
	p.libraryDecorator.moduleInfoJSON(ctx, moduleInfoJSON)
	moduleInfoJSON.SubName += p.androidMkSuffix
}

func (p *vndkPrebuiltLibraryDecorator) MatchesWithDevice(config android.DeviceConfig) bool {
	arches := config.Arches()
	if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
		return false
	}
	if config.BinderBitness() != p.binderBit() {
		return false
	}
	if len(p.properties.Srcs) == 0 {
		return false
	}
	return true
}

func (p *vndkPrebuiltLibraryDecorator) nativeCoverage() bool {
	return false
}

func (p *vndkPrebuiltLibraryDecorator) IsSnapshotPrebuilt() bool {
	return true
}

func (p *vndkPrebuiltLibraryDecorator) install(ctx ModuleContext, file android.Path) {
	// do not install vndk libs
}

func vndkPrebuiltSharedLibrary() *Module {
	module, library := NewLibrary(android.DeviceSupported)
	library.BuildOnlyShared()
	module.stl = nil
	module.sanitize = nil
	library.disableStripping()

	prebuilt := &vndkPrebuiltLibraryDecorator{
		libraryDecorator: library,
	}

	prebuilt.properties.Check_elf_files = BoolPtr(false)
	prebuilt.baseLinker.Properties.No_libcrt = BoolPtr(true)
	prebuilt.baseLinker.Properties.Nocrt = BoolPtr(true)
	prebuilt.baseLinker.Properties.No_crt_pad_segment = BoolPtr(true)

	// Prevent default system libs (libc, libm, and libdl) from being linked
	if prebuilt.baseLinker.Properties.System_shared_libs == nil {
		prebuilt.baseLinker.Properties.System_shared_libs = []string{}
	}

	module.compiler = nil
	module.linker = prebuilt
	module.installer = prebuilt

	module.AddProperties(
		&prebuilt.properties,
	)

	return module
}

// vndk_prebuilt_shared installs Vendor Native Development kit (VNDK) snapshot
// shared libraries for system build. Example:
//
//	vndk_prebuilt_shared {
//	    name: "libfoo",
//	    version: "27",
//	    target_arch: "arm64",
//	    vendor_available: true,
//	    product_available: true,
//	    vndk: {
//	        enabled: true,
//	    },
//	    export_include_dirs: ["include/external/libfoo/vndk_include"],
//	    arch: {
//	        arm64: {
//	            srcs: ["arm/lib64/libfoo.so"],
//	        },
//	        arm: {
//	            srcs: ["arm/lib/libfoo.so"],
//	        },
//	    },
//	}
func VndkPrebuiltSharedFactory() android.Module {
	module := vndkPrebuiltSharedLibrary()
	return module.Init()
}

func init() {
	android.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
}

func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool {
	if !m.Enabled(mctx) {
		return true
	}

	if p, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok {
		return p.MatchesWithDevice(mctx.DeviceConfig()) && Bool(p.properties.Vndk.Enabled)
	}
	return false
}
