// Copyright (C) 2019 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.

package sysprop

import (
	"android/soong/android"
	"android/soong/cc"
	"android/soong/java"
	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"
)

type dependencyTag struct {
	blueprint.BaseDependencyTag
	name string
}

type syspropLibrary struct {
	java.SdkLibrary

	commonProperties         commonProperties
	syspropLibraryProperties syspropLibraryProperties
}

type syspropLibraryProperties struct {
	// Determine who owns this sysprop library. Possible values are
	// "Platform", "Vendor", or "Odm"
	Property_owner string

	// list of package names that will be documented and publicized as API
	Api_packages []string
}

type commonProperties struct {
	Srcs               []string
	Recovery           *bool
	Recovery_available *bool
	Vendor_available   *bool
}

var (
	Bool         = proptools.Bool
	syspropCcTag = dependencyTag{name: "syspropCc"}
)

func init() {
	android.RegisterModuleType("sysprop_library", syspropLibraryFactory)
}

func (m *syspropLibrary) CcModuleName() string {
	return "lib" + m.Name()
}

func (m *syspropLibrary) SyspropJavaModule() *java.SdkLibrary {
	return &m.SdkLibrary
}

func syspropLibraryFactory() android.Module {
	m := &syspropLibrary{}

	m.AddProperties(
		&m.commonProperties,
		&m.syspropLibraryProperties,
	)
	m.InitSdkLibraryProperties()
	android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, "common")
	android.AddLoadHook(m, func(ctx android.LoadHookContext) { syspropLibraryHook(ctx, m) })

	return m
}

func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) {
	if m.syspropLibraryProperties.Api_packages == nil {
		ctx.PropertyErrorf("api_packages", "sysprop_library must specify api_packages")
	}

	socSpecific := ctx.SocSpecific()
	deviceSpecific := ctx.DeviceSpecific()
	productSpecific := ctx.ProductSpecific()

	owner := m.syspropLibraryProperties.Property_owner

	switch owner {
	case "Platform":
		// Every partition can access platform-defined properties
		break
	case "Vendor":
		// System can't access vendor's properties
		if !socSpecific && !deviceSpecific && !productSpecific {
			ctx.ModuleErrorf("None of soc_specific, device_specific, product_specific is true. " +
				"System can't access sysprop_library owned by Vendor")
		}
	case "Odm":
		// Only vendor can access Odm-defined properties
		if !socSpecific && !deviceSpecific {
			ctx.ModuleErrorf("Neither soc_speicifc nor device_specific is true. " +
				"Odm-defined properties should be accessed only in Vendor or Odm")
		}
	default:
		ctx.PropertyErrorf("property_owner",
			"Unknown value %s: must be one of Platform, Vendor or Odm", owner)
	}

	ccProps := struct {
		Name             *string
		Soc_specific     *bool
		Device_specific  *bool
		Product_specific *bool
		Sysprop          struct {
			Platform *bool
		}
	}{}

	ccProps.Name = proptools.StringPtr(m.CcModuleName())
	ccProps.Soc_specific = proptools.BoolPtr(socSpecific)
	ccProps.Device_specific = proptools.BoolPtr(deviceSpecific)
	ccProps.Product_specific = proptools.BoolPtr(productSpecific)
	ccProps.Sysprop.Platform = proptools.BoolPtr(owner == "Platform")

	ctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &m.commonProperties, &ccProps)
}
