// Copyright 2022 The Dawn 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 cov

import (
	"bytes"
	"encoding/binary"
	"encoding/json"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"dawn.googlesource.com/dawn/tools/src/fileutils"
)

// File describes the coverage spans in a single source file.
type File struct {
	Path      string
	Covered   SpanList // Spans with coverage
	Uncovered SpanList // Compiled spans without coverage
}

// Coverage describes the coverage spans for all the source files for a single
// process invocation.
type Coverage struct {
	Files []File
}

// Env holds the environment settings for performing coverage processing.
type Env struct {
	Profdata string // path to the llvm-profdata tool
	Binary   string // path to the executable binary
	Cov      string // path to the llvm-cov tool (one of Cov or TurboCov must be supplied)
	TurboCov string // path to the turbo-cov tool (one of Cov or TurboCov must be supplied)
}

// AllSourceFiles returns a *Coverage containing all the source files without
// coverage data. This populates the coverage view with files even if they
// didn't get compiled.
func (e Env) AllSourceFiles() *Coverage {
	var ignorePaths = map[string]bool{
		//
	}

	projectRoot := fileutils.DawnRoot()

	// Gather all the source files to include them even if there is no coverage
	// information produced for these files. This highlights files that aren't
	// even compiled.
	cov := Coverage{}
	allFiles := map[string]struct{}{}
	filepath.Walk(filepath.Join(projectRoot, "src"), func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		rel, err := filepath.Rel(projectRoot, path)
		if err != nil || ignorePaths[rel] {
			return filepath.SkipDir
		}
		if !info.IsDir() {
			switch filepath.Ext(path) {
			case ".h", ".c", ".cc", ".cpp", ".hpp":
				if _, seen := allFiles[rel]; !seen {
					cov.Files = append(cov.Files, File{Path: rel})
				}
			}
		}
		return nil
	})
	return &cov
}

// Import uses the llvm-profdata and llvm-cov tools to import the coverage
// information from a .profraw file.
func (e Env) Import(profrawPath string) (*Coverage, error) {
	profdata := profrawPath + ".profdata"
	defer os.Remove(profdata)

	if e.Profdata == "" {
		return nil, fmt.Errorf("cov.Env.Profdata must be specified")
	}
	if e.TurboCov == "" && e.Cov == "" {
		return nil, fmt.Errorf("One of cov.Env.TurboCov or cov.Env.Cov must be specified")
	}

	if out, err := exec.Command(
		e.Profdata,
		"merge",
		"-sparse",
		profrawPath,
		"-output",
		profdata).CombinedOutput(); err != nil {
		return nil, fmt.Errorf("llvm-profdata errored: %w\n%v", err, string(out))
	}

	if e.TurboCov == "" {
		data, err := exec.Command(
			e.Cov,
			"export",
			e.Binary,
			"-instr-profile="+profdata,
			"-format=text",
			"-skip-expansions",
			"-skip-functions").CombinedOutput()
		if err != nil {
			return nil, fmt.Errorf("llvm-cov errored: %v\n%v", string(data), err)
		}
		cov, err := e.parseCov(data)
		if err != nil {
			return nil, fmt.Errorf("failed to parse coverage json data: %w", err)
		}
		return cov, nil
	}

	data, err := exec.Command(e.TurboCov, e.Binary, profdata).CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("turbo-cov errored: %v\n%v", string(data), err)
	}
	cov, err := e.parseTurboCov(data)
	if err != nil {
		return nil, fmt.Errorf("failed to process turbo-cov output: %w", err)
	}

	return cov, nil
}

func appendSpan(spans []Span, span Span) []Span {
	if c := len(spans); c > 0 && spans[c-1].End == span.Start {
		spans[c-1].End = span.End
	} else {
		spans = append(spans, span)
	}
	return spans
}

// https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
// https://stackoverflow.com/a/56792192
func (e Env) parseCov(raw []byte) (*Coverage, error) {
	// line int, col int, count int64, hasCount bool, isRegionEntry bool
	type segment []interface{}

	type file struct {
		// expansions ignored
		Name     string    `json:"filename"`
		Segments []segment `json:"segments"`
		// summary ignored
	}

	type data struct {
		Files []file `json:"files"`
	}

	root := struct {
		Data []data `json:"data"`
	}{}
	err := json.NewDecoder(bytes.NewReader(raw)).Decode(&root)
	if err != nil {
		return nil, err
	}

	projectRoot := fileutils.DawnRoot()

	c := &Coverage{Files: make([]File, 0, len(root.Data[0].Files))}
	for _, f := range root.Data[0].Files {
		relpath, err := filepath.Rel(projectRoot, f.Name)
		if err != nil {
			return nil, err
		}
		if strings.HasPrefix(relpath, "..") {
			continue
		}
		file := File{Path: relpath}
		for sIdx := 0; sIdx+1 < len(f.Segments); sIdx++ {
			start := Location{(int)(f.Segments[sIdx][0].(float64)), (int)(f.Segments[sIdx][1].(float64))}
			end := Location{(int)(f.Segments[sIdx+1][0].(float64)), (int)(f.Segments[sIdx+1][1].(float64))}
			if covered := f.Segments[sIdx][2].(float64) != 0; covered {
				file.Covered = appendSpan(file.Covered, Span{start, end})
			} else {
				file.Uncovered = appendSpan(file.Uncovered, Span{start, end})
			}
		}
		if len(file.Covered) > 0 {
			c.Files = append(c.Files, file)
		}
	}

	return c, nil
}

// parseTurboCov parses coverage information from a `turbo-cov` file.
// See tools/src/cmd/turbo-cov/README.md for more information
func (e Env) parseTurboCov(data []byte) (*Coverage, error) {
	u32 := func() uint32 {
		out := binary.LittleEndian.Uint32(data)
		data = data[4:]
		return out
	}
	u8 := func() uint8 {
		out := data[0]
		data = data[1:]
		return out
	}
	str := func() string {
		len := u32()
		out := data[:len]
		data = data[len:]
		return string(out)
	}

	projectRoot := fileutils.DawnRoot()

	numFiles := u32()
	c := &Coverage{Files: make([]File, 0, numFiles)}
	for i := 0; i < int(numFiles); i++ {
		path := str()
		relpath, err := filepath.Rel(projectRoot, path)
		if err != nil {
			return nil, err
		}
		if strings.HasPrefix(relpath, "..") {
			continue
		}

		file := File{Path: relpath}

		type segment struct {
			location Location
			count    int
			covered  bool
		}

		numSegements := u32()
		segments := make([]segment, numSegements)
		for j := range segments {
			segment := &segments[j]
			segment.location.Line = int(u32())
			segment.location.Column = int(u32())
			segment.count = int(u32())
			segment.covered = u8() != 0
		}

		for sIdx := 0; sIdx+1 < len(segments); sIdx++ {
			start := segments[sIdx].location
			end := segments[sIdx+1].location
			if segments[sIdx].covered {
				if segments[sIdx].count > 0 {
					file.Covered = appendSpan(file.Covered, Span{start, end})
				} else {
					file.Uncovered = appendSpan(file.Uncovered, Span{start, end})
				}
			}
		}

		if len(file.Covered) > 0 {
			c.Files = append(c.Files, file)
		}
	}

	return c, nil
}

// Path uniquely identifies a test that was run to produce coverage.
// Paths are split into a hierarchical sequence of strings, where the 0'th
// string represents the root of the hierarchy and the last string is typically
// the leaf name of the test.
type Path []string
