// 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 bufcheck contains the implementations of the lint and breaking change detection rules.
//
// There is a lot of shared logic between the two, and originally they were actually combined into
// one logical entity (where some checks happened to be linters, and some checks happen to be
// breaking change detectors), so some of this is historical.
package bufcheck

import (
	"encoding/json"
	"fmt"
	"io"
	"strings"
	"text/tabwriter"

	"go.uber.org/multierr"
)

// AllRuleFormatStrings is all rule format strings.
var AllRuleFormatStrings = []string{
	"text",
	"json",
}

// Rule is a rule.
type Rule interface {
	json.Marshaler

	// ID returns the ID of the Rule.
	//
	// UPPER_SNAKE_CASE.
	ID() string
	// Categories returns the categories of the Rule.
	//
	// UPPER_SNAKE_CASE.
	// Sorted.
	// May be empty.
	Categories() []string
	// Purpose returns the purpose of the Rule.
	//
	// Full sentence.
	Purpose() string
}

// PrintRules prints the rules to the writer.
//
// The empty string defaults to text.
func PrintRules(writer io.Writer, rules []Rule, formatString string) (retErr error) {
	if len(rules) == 0 {
		return nil
	}
	var asJSON bool
	switch s := strings.ToLower(strings.TrimSpace(formatString)); s {
	case "", "text":
		asJSON = false
	case "json":
		asJSON = true
	default:
		return fmt.Errorf("unknown format: %q", s)
	}
	if !asJSON {
		tabWriter := tabwriter.NewWriter(writer, 0, 0, 2, ' ', 0)
		defer func() {
			retErr = multierr.Append(retErr, tabWriter.Flush())
		}()
		writer = tabWriter
		if _, err := fmt.Fprintln(writer, "ID\tCATEGORIES\tPURPOSE"); err != nil {
			return err
		}
	}
	for _, rule := range rules {
		if err := printRule(writer, rule, asJSON); err != nil {
			return err
		}
	}
	return nil
}

func printRule(writer io.Writer, rule Rule, asJSON bool) error {
	if asJSON {
		data, err := json.Marshal(rule)
		if err != nil {
			return err
		}
		if _, err := fmt.Fprintln(writer, string(data)); err != nil {
			return err
		}
		return nil
	}
	if _, err := fmt.Fprintf(writer, "%s\t%s\t%s\n", rule.ID(), strings.Join(rule.Categories(), ", "), rule.Purpose()); err != nil {
		return err
	}
	return nil
}
