// Copyright 2017 The LUCI Authors.
//
// 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 cfgmodule

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/klauspost/compress/gzip"
	"golang.org/x/sync/errgroup"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"google.golang.org/protobuf/types/known/emptypb"

	"go.chromium.org/luci/auth/identity"
	"go.chromium.org/luci/common/errors"
	"go.chromium.org/luci/common/logging"
	cfgpb "go.chromium.org/luci/common/proto/config"
	"go.chromium.org/luci/config"
	"go.chromium.org/luci/config/validation"
	"go.chromium.org/luci/server/auth"
	"go.chromium.org/luci/server/router"
)

const (
	// paths for handlers
	metadataPath   = "/api/config/v1/metadata"
	validationPath = "/api/config/v1/validate"

	// Taken from
	// https://chromium.googlesource.com/infra/luci/luci-py/+/3efc60daef6bf6669f9211f63e799db47a0478c0/appengine/components/components/config/endpoint.py
	metaDataFormatVersion = "1.0"
	adminGroup            = "administrators"
)

// ConsumerServer implements `cfgpb.Consumer` interface that will be called
// by LUCI Config.
type ConsumerServer struct {
	cfgpb.UnimplementedConsumerServer
	// Rules is a rule set to use for the config validation.
	Rules *validation.RuleSet
	// GetConfigServiceAccountFn returns a function that can fetch the service
	// account of the LUCI Config service. It is used by ACL checking.
	GetConfigServiceAccountFn func(context.Context) (string, error)
}

// GetMetadata implements cfgpb.Consumer.GetMetadata.
func (srv *ConsumerServer) GetMetadata(ctx context.Context, _ *emptypb.Empty) (*cfgpb.ServiceMetadata, error) {
	if err := srv.checkCaller(ctx); err != nil {
		return nil, err
	}
	patterns, err := srv.Rules.ConfigPatterns(ctx)
	if err != nil {
		return nil, status.Errorf(codes.Internal, "failed to collect the list of validation patterns: %s", err)
	}
	ret := &cfgpb.ServiceMetadata{}
	if len(patterns) > 0 {
		ret.ConfigPatterns = make([]*cfgpb.ConfigPattern, len(patterns))
		for i, pattern := range patterns {
			ret.ConfigPatterns[i] = &cfgpb.ConfigPattern{
				ConfigSet: pattern.ConfigSet.String(),
				Path:      pattern.Path.String(),
			}
		}
	}
	return ret, nil
}

// ValidateConfigs implements cfgpb.Consumer.ValidateConfigs.
func (srv *ConsumerServer) ValidateConfigs(ctx context.Context, req *cfgpb.ValidateConfigsRequest) (*cfgpb.ValidationResult, error) {
	if err := srv.checkCaller(ctx); err != nil {
		return nil, err
	}
	if err := checkValidateInput(req); err != nil {
		return nil, err
	}

	result := make([][]*cfgpb.ValidationResult_Message, len(req.GetFiles().GetFiles()))
	eg, ectx := errgroup.WithContext(ctx)
	eg.SetLimit(8)
	for i, file := range req.GetFiles().GetFiles() {
		i, file := i, file
		eg.Go(func() error {
			var content []byte
			switch file.GetContent().(type) {
			case *cfgpb.ValidateConfigsRequest_File_RawContent:
				content = file.GetRawContent()
			case *cfgpb.ValidateConfigsRequest_File_SignedUrl:
				tr, err := auth.GetRPCTransport(ctx, auth.NoAuth)
				if err != nil {
					return fmt.Errorf("failed to get the RPC transport: %w", err)
				}
				if content, err = config.DownloadConfigFromSignedURL(ectx, &http.Client{Transport: tr}, file.GetSignedUrl()); err != nil {
					return fmt.Errorf("failed to download file %s from the signed url: %w", file.Path, err)
				}
			default:
				panic(fmt.Errorf("unrecognized file content type: %T", file.GetContent()))
			}
			var err error
			result[i], err = srv.validateOneFile(ectx, req.GetConfigSet(), file.GetPath(), content)
			return err
		})
	}

	if err := eg.Wait(); err != nil {
		return nil, status.Errorf(codes.Internal, "encounter internal error: %s", err)
	}

	// Flatten the messages
	ret := &cfgpb.ValidationResult{}
	for _, msgs := range result {
		ret.Messages = append(ret.Messages, msgs...)
	}
	return ret, nil
}

// only LUCI Config and identity in admin group is allowed to call.
func (srv *ConsumerServer) checkCaller(ctx context.Context) error {
	configServiceAccount, err := srv.GetConfigServiceAccountFn(ctx)
	if err != nil {
		logging.Errorf(ctx, "Failed to get LUCI Config service account: %s", err)
		return status.Errorf(codes.Internal, "failed to get LUCI Config service account")
	}
	caller := auth.CurrentIdentity(ctx)
	if caller.Kind() == identity.User && caller.Value() == configServiceAccount {
		return nil
	}
	switch admin, err := auth.IsMember(ctx, adminGroup); {
	case err != nil:
		logging.Errorf(ctx, "Failed to check ACL: %s", err)
		return status.Errorf(codes.Internal, "failed to check ACL")
	case admin:
		return nil
	}
	return status.Errorf(codes.PermissionDenied, "%q is not authorized", caller)
}

func checkValidateInput(req *cfgpb.ValidateConfigsRequest) error {
	switch {
	case req.GetConfigSet() == "":
		return status.Errorf(codes.InvalidArgument, "must specify the config_set of the file to validate")
	case len(req.GetFiles().GetFiles()) == 0:
		return status.Errorf(codes.InvalidArgument, "must provide at least 1 file to validate")
	}
	for i, file := range req.GetFiles().GetFiles() {
		if file.GetPath() == "" {
			return status.Errorf(codes.InvalidArgument, "must specify path for file[%d]", i)
		}
		if file.GetRawContent() == nil && file.GetSignedUrl() == "" {
			return status.Errorf(codes.InvalidArgument, "must either provide raw_content or signed_url for file %q", file.GetPath())
		}
	}
	return nil
}

func (srv *ConsumerServer) validateOneFile(ctx context.Context, configSet, path string, content []byte) ([]*cfgpb.ValidationResult_Message, error) {
	vc := &validation.Context{Context: ctx}
	vc.SetFile(path)
	if err := srv.Rules.ValidateConfig(vc, configSet, path, content); err != nil {
		return nil, err
	}
	var vErr *validation.Error
	switch err := vc.Finalize(); {
	case errors.As(err, &vErr):
		return vErr.ToValidationResultMsgs(ctx), nil
	case err != nil:
		return []*cfgpb.ValidationResult_Message{
			{
				Path:     path,
				Severity: cfgpb.ValidationResult_ERROR,
				Text:     err.Error(),
			},
		}, nil
	default:
		return nil, nil
	}
}

// InstallHandlers installs the metadata and validation handlers that use
// the given validation rules.
//
// It does not implement any authentication checks, thus the passed in
// router.MiddlewareChain should implement any necessary authentication checks.
//
// Deprecated: The handlers are called by the legacy LUCI Config service. The
// new LUCI Config service will make request to `cfgpb.Consumer` prpc service
// instead. See `consumerServer`.
func InstallHandlers(r *router.Router, base router.MiddlewareChain, rules *validation.RuleSet) {
	r.GET(metadataPath, base, metadataRequestHandler(rules))
	r.POST(validationPath, base, validationRequestHandler(rules))
}

func badRequestStatus(c context.Context, w http.ResponseWriter, msg string, err error) {
	if err != nil {
		logging.WithError(err).Warningf(c, "%s", msg)
	} else {
		logging.Warningf(c, "%s", msg)
	}
	w.WriteHeader(http.StatusBadRequest)
	w.Write([]byte(msg))
}

func internalErrStatus(c context.Context, w http.ResponseWriter, msg string, err error) {
	logging.WithError(err).Errorf(c, "%s", msg)
	w.WriteHeader(http.StatusInternalServerError)
	w.Write([]byte(msg))
}

// validationRequestHandler handles the validation request from luci-config and
// responds with the corresponding results.
func validationRequestHandler(rules *validation.RuleSet) router.Handler {
	return func(ctx *router.Context) {
		c, w, r := ctx.Request.Context(), ctx.Writer, ctx.Request

		raw := r.Body
		if r.Header.Get("Content-Encoding") == "gzip" {
			logging.Infof(c, "The request is gzip compressed")
			var err error
			if raw, err = gzip.NewReader(r.Body); err != nil {
				badRequestStatus(c, w, "Failed to start decompressing gzip request body", err)
				return
			}
			defer raw.Close()
		}

		var reqBody cfgpb.ValidationRequestMessage
		switch err := json.NewDecoder(raw).Decode(&reqBody); {
		case err != nil:
			badRequestStatus(c, w, "Validation: error decoding request body", err)
			return
		case reqBody.GetConfigSet() == "":
			badRequestStatus(c, w, "Must specify the config_set of the file to validate", nil)
			return
		case reqBody.GetPath() == "":
			badRequestStatus(c, w, "Must specify the path of the file to validate", nil)
			return
		}

		vc := &validation.Context{Context: c}
		vc.SetFile(reqBody.GetPath())
		err := rules.ValidateConfig(vc, reqBody.GetConfigSet(), reqBody.GetPath(), reqBody.GetContent())
		if err != nil {
			internalErrStatus(c, w, "Validation: transient failure", err)
			return
		}

		var errors errors.MultiError
		verdict := vc.Finalize()
		if verr, _ := verdict.(*validation.Error); verr != nil {
			errors = verr.Errors
		} else if verdict != nil {
			errors = append(errors, verdict)
		}

		w.Header().Set("Content-Type", "application/json")
		var msgList []*cfgpb.ValidationResponseMessage_Message
		if len(errors) == 0 {
			logging.Infof(c, "No validation errors")
		} else {
			var errorBuffer bytes.Buffer
			for _, error := range errors {
				// validation.Context supports just 2 severities now,
				// but defensively default to ERROR level in unexpected cases.
				msgSeverity := cfgpb.ValidationResponseMessage_ERROR
				switch severity, ok := validation.SeverityTag.In(error); {
				case !ok:
					logging.Errorf(c, "unset validation.Severity in %s", error)
				case severity == validation.Warning:
					msgSeverity = cfgpb.ValidationResponseMessage_WARNING
				case severity != validation.Blocking:
					logging.Errorf(c, "unrecognized validation.Severity %d in %s", severity, error)
				}

				err := error.Error()
				msgList = append(msgList, &cfgpb.ValidationResponseMessage_Message{
					Severity: msgSeverity,
					Text:     err,
				})
				errorBuffer.WriteString("\n  " + err)
			}
			logging.Warningf(c, "Validation errors%s", errorBuffer.String())
		}
		if err := json.NewEncoder(w).Encode(cfgpb.ValidationResponseMessage{Messages: msgList}); err != nil {
			internalErrStatus(c, w, "Validation: failed to JSON encode output", err)
		}
	}
}

// metadataRequestHandler handles the metadata request from luci-config and
// responds with the necessary metadata defined by the given Validator.
func metadataRequestHandler(rules *validation.RuleSet) router.Handler {
	return func(ctx *router.Context) {
		c, w := ctx.Request.Context(), ctx.Writer

		patterns, err := rules.ConfigPatterns(c)
		if err != nil {
			internalErrStatus(c, w, "Metadata: failed to collect the list of validation patterns", err)
			return
		}

		meta := cfgpb.ServiceDynamicMetadata{
			Version:                 metaDataFormatVersion,
			SupportsGzipCompression: true,
			Validation: &cfgpb.Validator{
				Url: fmt.Sprintf("https://%s%s", ctx.Request.Host, validationPath),
			},
		}
		for _, p := range patterns {
			meta.Validation.Patterns = append(meta.Validation.Patterns, &cfgpb.ConfigPattern{
				ConfigSet: p.ConfigSet.String(),
				Path:      p.Path.String(),
			})
		}

		w.Header().Set("Content-Type", "application/json")
		if err := json.NewEncoder(w).Encode(&meta); err != nil {
			internalErrStatus(c, w, "Metadata: failed to JSON encode output", err)
		}
	}
}
