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

import (
	"path/filepath"
	"strconv"

	"android/soong/android"
	"android/soong/bazel"

	"github.com/google/blueprint/proptools"
)

const (
	protoTypeDefault = "lite"
)

func genProto(ctx android.ModuleContext, protoFiles android.Paths, flags android.ProtoFlags) android.Paths {
	// Shard proto files into groups of 100 to avoid having to recompile all of them if one changes and to avoid
	// hitting command line length limits.
	shards := android.ShardPaths(protoFiles, 50)

	srcJarFiles := make(android.Paths, 0, len(shards))

	for i, shard := range shards {
		srcJarFile := android.PathForModuleGen(ctx, "proto", "proto"+strconv.Itoa(i)+".srcjar")
		srcJarFiles = append(srcJarFiles, srcJarFile)

		outDir := srcJarFile.ReplaceExtension(ctx, "tmp")

		rule := android.NewRuleBuilder(pctx, ctx)

		rule.Command().Text("rm -rf").Flag(outDir.String())
		rule.Command().Text("mkdir -p").Flag(outDir.String())

		for _, protoFile := range shard {
			depFile := srcJarFile.InSameDir(ctx, protoFile.String()+".d")
			rule.Command().Text("mkdir -p").Flag(filepath.Dir(depFile.String()))
			android.ProtoRule(rule, protoFile, flags, flags.Deps, outDir, depFile, nil)
		}

		// Proto generated java files have an unknown package name in the path, so package the entire output directory
		// into a srcjar.
		rule.Command().
			BuiltTool("soong_zip").
			Flag("-srcjar").
			Flag("-write_if_changed").
			FlagWithOutput("-o ", srcJarFile).
			FlagWithArg("-C ", outDir.String()).
			FlagWithArg("-D ", outDir.String())

		rule.Command().Text("rm -rf").Flag(outDir.String())

		rule.Restat()

		ruleName := "protoc"
		ruleDesc := "protoc"
		if len(shards) > 1 {
			ruleName += "_" + strconv.Itoa(i)
			ruleDesc += " " + strconv.Itoa(i)
		}

		rule.Build(ruleName, ruleDesc)
	}

	return srcJarFiles
}

func protoDeps(ctx android.BottomUpMutatorContext, p *android.ProtoProperties) {
	const unspecifiedProtobufPluginType = ""
	if String(p.Proto.Plugin) == "" {
		switch String(p.Proto.Type) {
		case "stream": // does not require additional dependencies
		case "micro":
			ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-micro")
		case "nano":
			ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-nano")
		case "lite", unspecifiedProtobufPluginType:
			ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-lite")
		case "full":
			if ctx.Host() {
				ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-full")
			} else {
				ctx.PropertyErrorf("proto.type", "full java protos only supported on the host")
			}
		default:
			ctx.PropertyErrorf("proto.type", "unknown proto type %q",
				String(p.Proto.Type))
		}
	}
}

func protoFlags(ctx android.ModuleContext, j *CommonProperties, p *android.ProtoProperties,
	flags javaBuilderFlags) javaBuilderFlags {

	flags.proto = android.GetProtoFlags(ctx, p)

	if String(p.Proto.Plugin) == "" {
		var typeToPlugin string
		switch String(p.Proto.Type) {
		case "stream":
			flags.proto.OutTypeFlag = "--javastream_out"
			typeToPlugin = "javastream"
		case "micro":
			flags.proto.OutTypeFlag = "--javamicro_out"
			typeToPlugin = "javamicro"
		case "nano":
			flags.proto.OutTypeFlag = "--javanano_out"
			typeToPlugin = "javanano"
		case "lite", "":
			flags.proto.OutTypeFlag = "--java_out"
			flags.proto.OutParams = append(flags.proto.OutParams, "lite")
		case "full":
			flags.proto.OutTypeFlag = "--java_out"
		default:
			ctx.PropertyErrorf("proto.type", "unknown proto type %q",
				String(p.Proto.Type))
		}

		if typeToPlugin != "" {
			hostTool := ctx.Config().HostToolPath(ctx, "protoc-gen-"+typeToPlugin)
			flags.proto.Deps = append(flags.proto.Deps, hostTool)
			flags.proto.Flags = append(flags.proto.Flags, "--plugin=protoc-gen-"+typeToPlugin+"="+hostTool.String())
		}
	}

	flags.proto.OutParams = append(flags.proto.OutParams, j.Proto.Output_params...)

	return flags
}

type protoAttributes struct {
	Deps bazel.LabelListAttribute

	// A list of proto_library targets that the proto_library in `deps` depends on
	// This list is overestimation.
	// Overestimation is necessary since Soong includes other protos via proto.include_dirs and not
	// a specific .proto file module explicitly.
	Transitive_deps bazel.LabelListAttribute

	// This is the libs and the static_libs of the original java_library module.
	// On the bazel side, after proto sources are generated in java_*_proto_library, a java_library
	// will compile them. The libs and static_libs from the original java_library module need
	// to be linked because they are necessary in compile-time classpath.
	Additional_proto_deps bazel.LabelListAttribute

	Sdk_version  bazel.StringAttribute
	Java_version bazel.StringAttribute
}

func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute, AdditionalProtoDeps bazel.LabelListAttribute) *bazel.Label {
	protoInfo, ok := android.Bp2buildProtoProperties(ctx, &m.ModuleBase, protoSrcs)
	if !ok {
		return nil
	}

	typ := proptools.StringDefault(protoInfo.Type, protoTypeDefault)
	var rule_class string
	suffix := "_java_proto"
	switch typ {
	case "nano":
		suffix += "_nano"
		rule_class = "java_nano_proto_library"
	case "micro":
		suffix += "_micro"
		rule_class = "java_micro_proto_library"
	case "lite":
		suffix += "_lite"
		rule_class = "java_lite_proto_library"
	case "stream":
		suffix += "_stream"
		rule_class = "java_stream_proto_library"
	case "full":
		rule_class = "java_proto_library"
	default:
		ctx.PropertyErrorf("proto.type", "cannot handle conversion at this time: %q", typ)
	}

	protoAttrs := &protoAttributes{
		Deps:                  bazel.MakeLabelListAttribute(protoInfo.Proto_libs),
		Transitive_deps:       bazel.MakeLabelListAttribute(protoInfo.Transitive_proto_libs),
		Additional_proto_deps: AdditionalProtoDeps,
		Java_version:          bazel.StringAttribute{Value: m.properties.Java_version},
		Sdk_version:           bazel.StringAttribute{Value: m.deviceProperties.Sdk_version},
	}

	name := m.Name() + suffix

	ctx.CreateBazelTargetModule(
		bazel.BazelTargetModuleProperties{
			Rule_class:        rule_class,
			Bzl_load_location: "//build/bazel/rules/java:proto.bzl",
		},
		android.CommonAttributes{Name: name},
		protoAttrs)

	return &bazel.Label{Label: ":" + name}
}
