// Copyright 2018 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 main

import (
	"archive/tar"
	"bytes"
	"compress/gzip"
	"fmt"
	"io"
	"io/ioutil"
	"testing"
)

// FakeFile is a file-like io.ReadWriteCloser for testing.
type FakeFile struct {
	path string
	*bytes.Buffer
}

// The filepath of this FakeFile.
func (f *FakeFile) Name() string {
	return f.path
}

// Close implements io.WriteCloser.
func (f *FakeFile) Close() error {
	// Noop
	return nil
}

func NewFakeFile(path string, contents string) *FakeFile {
	return &FakeFile{
		Buffer: bytes.NewBuffer([]byte(contents)),
		path:   path,
	}
}

func checkTarContents(contents []byte, expectedTarFileContents map[string][]byte) error {
	var contentsBuffer bytes.Buffer
	contentsBuffer.Write(contents)
	// Open and iterate through the files in the archive.
	gzf, err := gzip.NewReader(&contentsBuffer)
	if err != nil {
		return fmt.Errorf("reading tarball failed, %v", err)
	}

	tr := tar.NewReader(gzf)
	actualTarFileContents := make(map[string][]byte)
	for {
		hdr, err := tr.Next()
		if err == io.EOF {
			break // End of archive.
		}
		if err != nil {
			return fmt.Errorf("reading tarball failed, %v", err)
		}
		actualData := make([]byte, hdr.Size)
		if _, err := tr.Read(actualData); err != nil && err != io.EOF {
			return fmt.Errorf("reading tarball data failed, %v", err)
		}
		actualTarFileContents[hdr.Name] = actualData
	}

	for expectedFileName, expectedFileContents := range expectedTarFileContents {
		actualFileContents, exist := actualTarFileContents[expectedFileName]
		if !exist {
			return fmt.Errorf("expecting %s to be found in tarball but not found", expectedFileName)
		}
		if !bytes.Equal(actualFileContents, expectedFileContents) {
			return fmt.Errorf("expecting contents in %s to be found same but not", expectedFileName)
		}
	}
	return nil
}

func TestRunCommand(t *testing.T) {
	// Expects dump_breakpad_symbols to produce the specified summary and
	// ninja depfile from the given input sources.
	expectOutputs := func(t *testing.T, inputs []*FakeFile, expectedDepFile string, expectedTarFileContents map[string][]byte, outDir string) {
		tarFile := NewFakeFile("breakpad_symbols.tar.gz", "")

		// Callback to mock executing the breakpad dump_syms binary.
		execDumpSyms := func(args []string) ([]byte, error) {
			return []byte("FAKE_SYMBOL_DATA_LINE_1\nFAKE_SYMBOL_DATA_LINE_2"), nil
		}

		// Callback to perform file I/O.
		createFile := func(path string) (io.ReadWriteCloser, error) {
			return NewFakeFile(path, ""), nil
		}

		// Convert input files from `[]FakeFile` to `[]io.Reader`.
		fileReaders := make([]io.Reader, len(inputs))
		for i := range inputs {
			fileReaders[i] = inputs[i]
		}

		// Process the input files.
		summary := processIdsFiles(fileReaders, outDir, execDumpSyms, createFile)

		// Write the tarball file.
		if err := writeTarball(tarFile, summary, outDir); err != nil {
			t.Fatalf("failed to write tarball %s: %v", tarFile.Name(), err)
		}

		// Extract input filepaths.
		inputPaths := make([]string, len(inputs))
		for i := range inputs {
			inputPaths[i] = inputs[i].Name()
		}

		// Expect matching tarball.
		actualTarFile, err := ioutil.ReadAll(tarFile)
		if err != nil {
			t.Fatal(err)
		}
		if err := checkTarContents(actualTarFile, expectedTarFileContents); err != nil {
			t.Fatalf("%v", err)
		}
	}

	t.Run("should produce an emtpy summary if no data is provided", func(t *testing.T) {
		inputSources := []*FakeFile{
			NewFakeFile("idsA.txt", ""),
			NewFakeFile("idsB.txt", ""),
		}
		expectedDepFile := fmt.Sprintf("breakpad_symbols.tar.gz: %s %s\n", "idsA.txt", "idsB.txt")
		expectOutputs(t, inputSources, expectedDepFile, make(map[string][]byte), "out/")
	})
}

// No tests to verify the output of dump_syms. Assume it does the right thing.
