// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You 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 bufpluginexec

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
)

import (
	"google.golang.org/protobuf/proto"

	"google.golang.org/protobuf/types/pluginpb"
)

func newVersion(major int32, minor int32, patch int32, suffix string) *pluginpb.Version {
	version := &pluginpb.Version{
		Major: proto.Int32(major),
		Minor: proto.Int32(minor),
		Patch: proto.Int32(patch),
	}
	if suffix != "" {
		version.Suffix = proto.String(suffix)
	}
	return version
}

func parseVersionForCLIVersion(value string) (_ *pluginpb.Version, retErr error) {
	defer func() {
		if retErr != nil {
			retErr = fmt.Errorf("cannot parse protoc version %q: %w", value, retErr)
		}
	}()

	// protoc always starts with "libprotoc "
	value = strings.TrimPrefix(value, "libprotoc ")
	split := strings.Split(value, ".")
	if n := len(split); n != 2 && n != 3 {
		return nil, fmt.Errorf("%d components split by '.'", n)
	}
	major, err := strconv.ParseInt(split[0], 10, 32)
	if err != nil {
		return nil, err
	}
	var suffix string
	restSplit := strings.SplitN(split[len(split)-1], "-", 2)
	lastNumber, err := strconv.ParseInt(restSplit[0], 10, 32)
	if err != nil {
		return nil, err
	}
	switch len(restSplit) {
	case 1:
	case 2:
		suffix = restSplit[1]
	default:
		return nil, errors.New("more than two patch components split by '-'")
	}
	var minor int64
	var patch int64
	switch len(split) {
	case 2:
		minor = lastNumber
	case 3:
		minor, err = strconv.ParseInt(split[1], 10, 32)
		if err != nil {
			return nil, err
		}
		patch = lastNumber
	}
	return newVersion(int32(major), int32(minor), int32(patch), suffix), nil
}

func versionString(version *pluginpb.Version) string {
	var value string
	if version.GetMajor() <= 3 || version.GetPatch() != 0 {
		value = fmt.Sprintf("%d.%d.%d", version.GetMajor(), version.GetMinor(), version.GetPatch())
	} else {
		value = fmt.Sprintf("%d.%d", version.GetMajor(), version.GetMinor())
	}
	if version.Suffix != nil {
		value = value + "-" + version.GetSuffix()
	}
	return value
}

// Should I set the --experimental_allow_proto3_optional flag?
func getSetExperimentalAllowProto3OptionalFlag(version *pluginpb.Version) bool {
	if version.GetSuffix() == "buf" {
		return false
	}
	if version.GetMajor() != 3 {
		return false
	}
	return version.GetMinor() > 11 && version.GetMinor() < 15
}

// Should I notify that I am OK with the proto3 optional feature?
func getFeatureProto3OptionalSupported(version *pluginpb.Version) bool {
	if version.GetSuffix() == "buf" {
		return true
	}
	if version.GetMajor() < 3 {
		return false
	}
	if version.GetMajor() == 3 {
		return version.GetMinor() > 11
	}
	// version.GetMajor() > 3
	return true
}

// Is kotlin supported as a builtin plugin?
func getKotlinSupportedAsBuiltin(version *pluginpb.Version) bool {
	if version.GetSuffix() == "buf" {
		return true
	}
	if version.GetMajor() < 3 {
		return false
	}
	if version.GetMajor() == 3 {
		return version.GetMinor() > 16
	}
	// version.GetMajor() > 3
	return true
}

// Is js supported as a builtin plugin?
func getJSSupportedAsBuiltin(version *pluginpb.Version) bool {
	if version.GetSuffix() == "buf" {
		return true
	}
	if version.GetMajor() < 3 {
		return false
	}
	if version.GetMajor() == 3 {
		// v21 and above of protoc still returns "3.MAJOR.Z" for version
		return version.GetMinor() < 21
	}
	// version.GetMajor() > 3
	// This will catch if they ever change protoc's returned version
	// to the proper major version
	return false
}
