// Copyright 2021 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 snapshot

import (
	"encoding/json"
	"path/filepath"

	"android/soong/android"
)

// The host_snapshot module creates a snapshot of host tools to be used
// in a minimal source tree.   In order to create the host_snapshot the
// user must explicitly list the modules to be included.  The
// host-fake-snapshot, defined in this file, is a utility to help determine
// which host modules are being used in the minimal source tree.
//
// The host-fake-snapshot is designed to run in a full source tree and
// will result in a snapshot that contains an empty file for each host
// tool found in the tree.  The fake snapshot is only used to determine
// the host modules that the minimal source tree depends on, hence the
// snapshot uses an empty file for each module and saves on having to
// actually build any tool to generate the snapshot.  The fake snapshot
// is compatible with an actual host_snapshot and is installed into a
// minimal source tree via the development/vendor_snapshot/update.py
// script.
//
// After generating the fake snapshot and installing into the minimal
// source tree, the dependent modules are determined via the
// development/vendor_snapshot/update.py script (see script for more
// information).  These modules are then used to define the actual
// host_snapshot to be used.  This is a similar process to the other
// snapshots (vendor, recovery,...)
//
// Example
//
// Full source tree:
//   1/ Generate fake host snapshot
//
// Minimal source tree:
//   2/ Install the fake host snapshot
//   3/ List the host modules used from the snapshot
//   4/ Remove fake host snapshot
//
// Full source tree:
//   4/ Create host_snapshot with modules identified in step 3
//
// Minimal source tree:
//   5/ Install host snapshot
//   6/ Build
//
// The host-fake-snapshot is a singleton module, that will be built
// if HOST_FAKE_SNAPSHOT_ENABLE=true.

func init() {
	registerHostSnapshotComponents(android.InitRegistrationContext)
}

// Add prebuilt information to snapshot data
type hostSnapshotFakeJsonFlags struct {
	SnapshotJsonFlags
	Prebuilt bool `json:",omitempty"`
}

func registerHostSnapshotComponents(ctx android.RegistrationContext) {
	ctx.RegisterParallelSingletonType("host-fake-snapshot", HostToolsFakeAndroidSingleton)
}

type hostFakeSingleton struct {
	snapshotDir string
	zipFile     android.OptionalPath
}

func (c *hostFakeSingleton) init() {
	c.snapshotDir = "host-fake-snapshot"

}
func HostToolsFakeAndroidSingleton() android.Singleton {
	singleton := &hostFakeSingleton{}
	singleton.init()
	return singleton
}

func (c *hostFakeSingleton) GenerateBuildActions(ctx android.SingletonContext) {
	if !ctx.DeviceConfig().HostFakeSnapshotEnabled() {
		return
	}
	// Find all host binary modules add 'fake' versions to snapshot
	var outputs android.Paths
	seen := make(map[string]bool)
	var jsonData []hostSnapshotFakeJsonFlags
	prebuilts := make(map[string]bool)

	ctx.VisitAllModules(func(module android.Module) {
		if module.Target().Os != ctx.Config().BuildOSTarget.Os {
			return
		}
		if module.Target().Arch.ArchType != ctx.Config().BuildOSTarget.Arch.ArchType {
			return
		}

		if android.IsModulePrebuilt(module) {
			// Add non-prebuilt module name to map of prebuilts
			prebuilts[android.RemoveOptionalPrebuiltPrefix(module.Name())] = true
			return
		}
		if !module.Enabled() || module.IsHideFromMake() {
			return
		}
		apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
		if !apexInfo.IsForPlatform() {
			return
		}
		path := hostToolPath(module)
		if path.Valid() && path.String() != "" {
			outFile := filepath.Join(c.snapshotDir, path.String())
			if !seen[outFile] {
				seen[outFile] = true
				outputs = append(outputs, WriteStringToFileRule(ctx, "", outFile))
				jsonData = append(jsonData, hostSnapshotFakeJsonFlags{*hostJsonDesc(module), false})
			}
		}
	})
	// Update any module prebuilt information
	for idx, _ := range jsonData {
		if _, ok := prebuilts[jsonData[idx].ModuleName]; ok {
			// Prebuilt exists for this module
			jsonData[idx].Prebuilt = true
		}
	}
	marsh, err := json.Marshal(jsonData)
	if err != nil {
		ctx.Errorf("host fake snapshot json marshal failure: %#v", err)
		return
	}
	outputs = append(outputs, WriteStringToFileRule(ctx, string(marsh), filepath.Join(c.snapshotDir, "host_snapshot.json")))
	c.zipFile = zipSnapshot(ctx, c.snapshotDir, c.snapshotDir, outputs)

}
func (c *hostFakeSingleton) MakeVars(ctx android.MakeVarsContext) {
	if !c.zipFile.Valid() {
		return
	}
	ctx.Phony(
		"host-fake-snapshot",
		c.zipFile.Path())

	ctx.DistForGoal(
		"host-fake-snapshot",
		c.zipFile.Path())

}
