// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package apidiff

import (
	"encoding/json"
	"fmt"
	"io"

	"go.fuchsia.dev/fuchsia/tools/fidl/lib/summarize"
)

// Classification describes the compatibility of a change.
type Classification string

const (
	// NeedsBackfill means the change could not be classified on its own, but
	// requires another pass where its enclosing declaration is known. See
	// backfillForParentStrictness().
	NeedsBackfill Classification = "NeedsBackfill"
	// Compatible means the change is both API and ABI compatible.
	Compatible Classification = "Compatible"
	// APIBreaking means the change will break compilation. It might also break
	// ABI; we don't distinguish between API breaks and API+ABI breaks.
	APIBreaking Classification = "APIBreaking"
	// APICompatibleButABIBreaking is used to reject the small category of
	// changes which break ABI without also breaking API.
	APICompatibleButABIBreaking Classification = "APICompatibleButABIBreaking"
)

// ReportItem is a single line item of the API diff report.
type ReportItem struct {
	// Name is the fully qualified name that this report item
	// pertains to.
	Name summarize.Name `json:"name"`
	// Before is what the API summary used to look like.
	Before *summarize.ElementStr `json:"before,omitempty"`
	// After is what the API summary looks like now.
	After *summarize.ElementStr `json:"after,omitempty"`
	// Conclusion is the finding.
	Conclusion Classification `json:"conclusion"`
}

func (r ReportItem) IsAdd() bool {
	return r.Before == nil && r.After != nil
}

func (r ReportItem) IsRemove() bool {
	return r.Before != nil && r.After == nil
}

func (r ReportItem) IsChange() bool {
	return r.Before != nil && r.After != nil
}

// Report is a top-level wrapper for the API diff result.
type Report struct {
	// APIDiff has the report items for each individual change of the API
	// surface for a FIDL library.
	APIDiff []ReportItem `json:"api_diff,omitempty"`

	// backfillIndexes contains APIDiff indexes which have a NeedsBackfill
	// classification, to be handled by backfillForParentStrictness().
	backfillIndexes []int
}

// backfillForParentStrictness backfills all APIDiff indexes based on the given
// strictness. This is called when processing a declaration, after having
// already processed its members (and put them in r.backfillIndexes).
func (r *Report) backfillForParentStrictness(isStrict bool) {
	for _, i := range r.backfillIndexes {
		if isStrict {
			r.APIDiff[i].Conclusion = APIBreaking
		} else {
			r.APIDiff[i].Conclusion = Compatible
		}
	}
	r.backfillIndexes = nil
}

func (r *Report) addToDiff(rep ReportItem) {
	switch rep.Conclusion {
	case "":
		panic(fmt.Sprintf("unset conclusion: %+v", rep))
	case NeedsBackfill:
		r.backfillIndexes = append(r.backfillIndexes, len(r.APIDiff))
	}
	r.APIDiff = append(r.APIDiff, rep)
}

// WriteJSON writes a report as JSON.
func (r Report) WriteJSON(w io.Writer) error {
	e := json.NewEncoder(w)
	e.SetEscapeHTML(false)
	e.SetIndent("", "    ")
	if err := e.Encode(r); err != nil {
		return fmt.Errorf("while writing JSON: %w", err)
	}
	return nil
}

// add processes a single added ElementStr.
func (r *Report) add(item *summarize.ElementStr) {
	ret := ReportItem{
		Name:  item.Name,
		After: item,
	}
	switch item.Kind {
	case summarize.BitsKind,
		summarize.EnumKind,
		summarize.StructKind,
		summarize.LibraryKind,
		summarize.ConstKind,
		summarize.TableKind,
		summarize.UnionKind,
		summarize.ProtocolKind,
		summarize.AliasKind,
		summarize.TableMemberKind,
		summarize.BitsMemberKind:
		ret.Conclusion = Compatible
	case summarize.EnumMemberKind, summarize.UnionMemberKind, summarize.StructMemberKind:
		// Adding a member to a struct or a strict enum/union is compatible iff
		// the parent struct/enum/union is also being added, i.e. this is one of
		// its initial members. Adding a member to a flexible enum/union is
		// always compatible. We need to backfill for this information.
		ret.Conclusion = NeedsBackfill
	case summarize.ProtocolMemberKind:
		// TODO(https://fxbug.dev/42078310): Technically, adding a method is API breaking
		// because server implementations will fail to compile if they don't
		// handle the new method. To avoid this you can use the @transitional
		// attribute, and remove it once all servers are updated. We are not
		// tracking this now for two reasons:
		//
		// 1. It's common to add methods to protocols that have no server
		//    implementations outside the platform. Requiring @transitional
		//    in these cases is unnecessary and will slow us down.
		//
		// 2. Removing the @transitional attribute requires duplicating the
		//    method definition: https://fuchsia.dev/fuchsia-src/reference/fidl/language/versioning?hl=en#swapping.
		//    We should improve the syntax (e.g. integrate into @available)
		//    before requiring all new methods to be @transitional.
		ret.Conclusion = Compatible
	default:
		panic(fmt.Sprintf("unexpected item kind: %+v", item))
	}
	r.addToDiff(ret)
}

// remove processes a single removed ElementStr.
func (r *Report) remove(item *summarize.ElementStr) {
	ret := ReportItem{
		Name:       item.Name,
		Before:     item,
		Conclusion: APIBreaking,
	}
	r.addToDiff(ret)
}

func (r *Report) compare(before, after *summarize.ElementStr) {
	if *before == *after {
		// No change
		return
	}
	ret := ReportItem{
		Name:   after.Name,
		Before: before,
		After:  after,
	}
	switch {
	case before.Name != after.Name:
		panic(fmt.Sprintf("before name %q != after name %q", before.Name, after.Name))
	case before.Kind != after.Kind,
		before.Strictness != after.Strictness,
		before.Resourceness != after.Resourceness,
		before.Type != after.Type,
		before.Value != after.Value,
		before.Openness != after.Openness,
		before.Transport != after.Transport,
		before.Direction != after.Direction,
		before.Request != after.Request,
		before.Response != after.Response,
		before.Error != after.Error:
		ret.Conclusion = APIBreaking
	case before.Ordinal != after.Ordinal:
		if before.Kind == "struct/member" {
			// Reordering struct members breaks API due to positional
			// initializers in C++. (It of course breaks ABI too.)
			ret.Conclusion = APIBreaking
		} else {
			// Changing table/union/method ordinals breaks ABI only.
			ret.Conclusion = APICompatibleButABIBreaking
		}
	default:
		panic(fmt.Sprintf("unexpected difference: before = %+v, after = %+v", before, after))
	}
	r.addToDiff(ret)
}
