// 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 python

// This file contains the module types for building Python binary.

import (
	"fmt"
	"path/filepath"
	"strings"

	"github.com/google/blueprint"

	"android/soong/android"
)

func init() {
	android.RegisterModuleType("python_binary_host", PythonBinaryHostFactory)
}

type PythonBinaryBaseProperties struct {
	// the name of the source file that is the main entry point of the program.
	// this file must also be listed in srcs.
	// If left unspecified, module name is used instead.
	// If name doesn’t match any filename in srcs, main must be specified.
	Main string

	// set the name of the output binary.
	Stem string

	// append to the name of the output binary.
	Suffix string
}

type pythonBinaryBase struct {
	pythonBaseModule

	binaryProperties PythonBinaryBaseProperties

	// soong_zip arguments from all its dependencies.
	depsParSpecs []parSpec

	// Python runfiles paths from all its dependencies.
	depsPyRunfiles []string
}

type PythonBinaryHost struct {
	pythonBinaryBase
}

var _ PythonSubModule = (*PythonBinaryHost)(nil)

type pythonBinaryHostDecorator struct {
	pythonDecorator
}

func (p *pythonBinaryHostDecorator) install(ctx android.ModuleContext, file android.Path) {
	p.pythonDecorator.baseInstaller.install(ctx, file)
}

var (
	stubTemplateHost = "build/soong/python/scripts/stub_template_host.txt"
)

func PythonBinaryHostFactory() (blueprint.Module, []interface{}) {
	decorator := &pythonBinaryHostDecorator{
		pythonDecorator: pythonDecorator{baseInstaller: NewPythonInstaller("bin")}}

	module := &PythonBinaryHost{}
	module.pythonBaseModule.installer = decorator

	return InitPythonBaseModule(&module.pythonBinaryBase.pythonBaseModule,
		&module.pythonBinaryBase, android.HostSupportedNoCross, &module.binaryProperties)
}

func (p *pythonBinaryBase) GeneratePythonBuildActions(ctx android.ModuleContext) android.OptionalPath {
	p.pythonBaseModule.GeneratePythonBuildActions(ctx)

	// no Python source file for compiling par file.
	if len(p.pythonBaseModule.srcsPathMappings) == 0 && len(p.depsPyRunfiles) == 0 {
		return android.OptionalPath{}
	}

	// the runfiles packages needs to be populated with "__init__.py".
	newPyPkgs := []string{}
	// the set to de-duplicate the new Python packages above.
	newPyPkgSet := make(map[string]bool)
	// the runfiles dirs have been treated as packages.
	existingPyPkgSet := make(map[string]bool)

	wholePyRunfiles := []string{}
	for _, path := range p.pythonBaseModule.srcsPathMappings {
		wholePyRunfiles = append(wholePyRunfiles, path.dest)
	}
	wholePyRunfiles = append(wholePyRunfiles, p.depsPyRunfiles...)

	// find all the runfiles dirs which have been treated as packages.
	for _, path := range wholePyRunfiles {
		if filepath.Base(path) != initFileName {
			continue
		}
		existingPyPkg := PathBeforeLastSlash(path)
		if _, found := existingPyPkgSet[existingPyPkg]; found {
			panic(fmt.Errorf("found init file path duplicates: %q for module: %q.",
				path, ctx.ModuleName()))
		} else {
			existingPyPkgSet[existingPyPkg] = true
		}
		parentPath := PathBeforeLastSlash(existingPyPkg)
		populateNewPyPkgs(parentPath, existingPyPkgSet, newPyPkgSet, &newPyPkgs)
	}

	// create new packages under runfiles tree.
	for _, path := range wholePyRunfiles {
		if filepath.Base(path) == initFileName {
			continue
		}
		parentPath := PathBeforeLastSlash(path)
		populateNewPyPkgs(parentPath, existingPyPkgSet, newPyPkgSet, &newPyPkgs)
	}

	main := p.getPyMainFile(ctx)
	if main == "" {
		return android.OptionalPath{}
	}
	interp := p.getInterpreter(ctx)
	if interp == "" {
		return android.OptionalPath{}
	}

	// we need remove "runfiles/" suffix since stub script starts
	// searching for main file in each sub-dir of "runfiles" directory tree.
	binFile := registerBuildActionForParFile(ctx, p.getInterpreter(ctx),
		strings.TrimPrefix(main, runFiles+"/"), p.getStem(ctx),
		newPyPkgs, append(p.depsParSpecs, p.pythonBaseModule.parSpec))

	return android.OptionalPathForPath(binFile)
}

// get interpreter path.
func (p *pythonBinaryBase) getInterpreter(ctx android.ModuleContext) string {
	var interp string
	switch p.pythonBaseModule.properties.ActualVersion {
	case pyVersion2:
		interp = "python2"
	case pyVersion3:
		interp = "python3"
	default:
		panic(fmt.Errorf("unknown Python actualVersion: %q for module: %q.",
			p.properties.ActualVersion, ctx.ModuleName()))
	}

	return interp
}

// find main program path within runfiles tree.
func (p *pythonBinaryBase) getPyMainFile(ctx android.ModuleContext) string {
	var main string
	if p.binaryProperties.Main == "" {
		main = p.BaseModuleName() + pyExt
	} else {
		main = p.binaryProperties.Main
	}

	for _, path := range p.pythonBaseModule.srcsPathMappings {
		if main == path.src.Rel() {
			return path.dest
		}
	}
	ctx.PropertyErrorf("main", "%q is not listed in srcs.", main)

	return ""
}

func (p *pythonBinaryBase) getStem(ctx android.ModuleContext) string {
	stem := ctx.ModuleName()
	if p.binaryProperties.Stem != "" {
		stem = p.binaryProperties.Stem
	}

	return stem + p.binaryProperties.Suffix
}

// Sets the given directory and all its ancestor directories as Python packages.
func populateNewPyPkgs(pkgPath string, existingPyPkgSet,
	newPyPkgSet map[string]bool, newPyPkgs *[]string) {
	for pkgPath != "" {
		if _, found := existingPyPkgSet[pkgPath]; found {
			break
		}
		if _, found := newPyPkgSet[pkgPath]; !found {
			newPyPkgSet[pkgPath] = true
			*newPyPkgs = append(*newPyPkgs, pkgPath)
			// Gets its ancestor directory by trimming last slash.
			pkgPath = PathBeforeLastSlash(pkgPath)
		} else {
			break
		}
	}
}

// filepath.Dir("abc") -> "." and filepath.Dir("/abc") -> "/". However,
// the PathBeforeLastSlash() will return "" for both cases above.
func PathBeforeLastSlash(path string) string {
	if idx := strings.LastIndex(path, "/"); idx != -1 {
		return path[:idx]
	}
	return ""
}
