// Copyright 2023 The Shac 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 reporting

import (
	"context"
	"io"
	"sort"
	"sync"
	"time"

	"go.fuchsia.dev/shac-project/shac/internal/engine"
	"go.fuchsia.dev/shac-project/shac/internal/sarif"
	"google.golang.org/protobuf/encoding/protojson"
)

// SarifReport converts findings into SARIF JSON output.
type SarifReport struct {
	// SARIF output gets written here when Close() is called.
	Out io.Writer

	mu             sync.Mutex
	resultsByCheck map[string][]*sarif.Result
}

func (sr *SarifReport) EmitFinding(ctx context.Context, check string, level engine.Level, message, root, file string, s engine.Span, replacements []string) error {
	levelMap := map[engine.Level]string{
		engine.Notice:  sarif.Note,
		engine.Warning: sarif.Warning,
		engine.Error:   sarif.Error,
	}
	region := &sarif.Region{
		StartLine:   int32(s.Start.Line),
		EndLine:     int32(s.End.Line),
		StartColumn: int32(s.Start.Col),
		EndColumn:   int32(s.End.Col),
	}

	var fixes []*sarif.Fix
	for _, repl := range replacements {
		fixes = append(fixes, &sarif.Fix{
			ArtifactChanges: []*sarif.ArtifactChange{
				{
					ArtifactLocation: &sarif.ArtifactLocation{Uri: file},
					Replacements: []*sarif.Replacement{
						{
							DeletedRegion:   region,
							InsertedContent: &sarif.ArtifactContent{Text: repl},
						},
					},
				},
			},
		})
	}

	result := &sarif.Result{
		// TODO(olivernewman): Set RuleId field. The SARIF specification states
		// that ruleId "SHALL" be set, and "Not all existing analysis tools emit
		// the equivalent of a ruleId in their output. A SARIF converter which
		// converts the output of such an analysis tool to the SARIF format
		// SHOULD synthesize ruleId from other information available in the
		// analysis tool's output."
		// https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317643
		Level:   levelMap[level],
		Message: &sarif.Message{Text: message},
		Locations: []*sarif.Location{
			{
				PhysicalLocation: &sarif.PhysicalLocation{
					ArtifactLocation: &sarif.ArtifactLocation{Uri: file},
					Region:           region,
				},
			},
		},
		Fixes: fixes,
	}

	sr.mu.Lock()
	if sr.resultsByCheck == nil {
		sr.resultsByCheck = make(map[string][]*sarif.Result)
	}
	sr.resultsByCheck[check] = append(sr.resultsByCheck[check], result)
	sr.mu.Unlock()

	return nil
}

func (sr *SarifReport) EmitArtifact(ctx context.Context, root, check, file string, content []byte) error {
	// TODO(olivernewman): Emit artifacts via the `artifacts` SARIF property:
	// https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317499
	return nil
}

func (sr *SarifReport) CheckCompleted(ctx context.Context, check string, start time.Time, d time.Duration, level engine.Level, err error) {
}

func (sr *SarifReport) Print(context.Context, string, string, int, string) {}

func (sr *SarifReport) Close() error {
	doc := &sarif.Document{Version: sarif.Version}
	// Sort for determinism.
	var sortedChecks []string
	for check := range sr.resultsByCheck {
		sortedChecks = append(sortedChecks, check)
	}
	sort.Strings(sortedChecks)

	for _, check := range sortedChecks {
		results := sr.resultsByCheck[check]
		doc.Runs = append(doc.Runs, &sarif.Run{
			Tool: &sarif.Tool{
				Driver: &sarif.ToolComponent{Name: check},
			},
			Results: results,
		})
	}

	b, err := protojson.MarshalOptions{
		Multiline:     true,
		UseProtoNames: false,
	}.Marshal(doc)
	if err != nil {
		return err
	}
	_, err = sr.Out.Write(b)
	return err
}
