// Copyright 2015 The Chromium 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 parser

import (
	"fmt"
	"mojom/mojom_parser/mojom"
	"os"
	"path/filepath"
	"reflect"
	"strings"
	"testing"
)

// FakeFileProvider implements FileProvider.
type FakeFileProvider struct {
	// This field records the names of the files whose contents were requested.
	requestedFileNames []string
}

// FakeFileProvider implements provideContents by recording the name of the file
// whose contents are being requested and then returning the empty string.
func (f *FakeFileProvider) provideContents(fileRef *FileReference) (contents string, fileReadError error) {
	f.requestedFileNames = append(f.requestedFileNames, fileRef.specifiedPath)
	return "", nil
}

// FakeFileProvider implements findFile by always succeeding to find the
// file and reporting that the |absolutePath| is equal to the |specifiedPath|
// with the prefix "/a/b/c/"
func (f *FakeFileProvider) findFile(fileRef *FileReference) error {
	fileRef.absolutePath = fmt.Sprintf("/a/b/c/%s", fileRef.specifiedPath)
	return nil
}

type NoOpParseInvoker int

func (NoOpParseInvoker) invokeParse(parser *Parser) {}

// FakeFileExtractor implements FileExtractor
type FakeFileExtractor struct {
	// This field maps a file name to the set of import names that we want to
	// simulate the given file is importing.
	importNames map[string][]string
}

func makeFakeFileExtractor() FakeFileExtractor {
	extractor := FakeFileExtractor{}
	extractor.importNames = make(map[string][]string)
	return extractor
}

// Invoke this method to specify that FakeFileExtractor should simulate the fact
// that the file named |fileName| imports the files specified by |imports|.
func (f *FakeFileExtractor) appendImportsToFile(fileName string, imports ...string) {
	if imports != nil {
		f.importNames[fileName] = append(f.importNames[fileName], imports...)
	}
}

// FakeFileExtractor implements extractMojomFile() by returning an instance
// of MojomFile that has had imports added to it according to the values
// in the map |importNames|.
func (f *FakeFileExtractor) extractMojomFile(parser *Parser) *mojom.MojomFile {
	file := parser.GetMojomFile()
	for _, importName := range f.importNames[file.CanonicalFileName] {
		file.AddImport(importName)
	}
	return file
}

// TestExpectedFilesParsed tests the logic in function ParseDriver.ParseFiles()
// for determining which files should be parsed.
func TestExpectedFilesParsed(t *testing.T) {
	// Construct our fake objects.
	fakeFileProvider := FakeFileProvider{}
	fakeFileExtractor := makeFakeFileExtractor()
	// Our fake file1 will import file3, file4, file5
	fakeFileExtractor.appendImportsToFile("/a/b/c/file1", "file3", "file4", "file5")
	// Our fake file5 will import file1 and file6
	fakeFileExtractor.appendImportsToFile("/a/b/c/file5", "file1", "file6")

	// Construct the driver under test
	driver := newDriver([]string{}, false, &fakeFileProvider, &fakeFileExtractor, NoOpParseInvoker(0))

	// Invoke ParseFiles with file1, file2 and file3 as top-level files.
	descriptor, err := driver.ParseFiles([]string{"file1", "file2", "file3"})
	if err != nil {
		t.Errorf(err.Error())
	}

	// Check that the correct files had their contents requested in the expected order.
	expectedFileRefs := []string{"file1", "file2", "file3", "file4", "file5", "file6"}
	if !reflect.DeepEqual(expectedFileRefs, fakeFileProvider.requestedFileNames) {
		t.Errorf("%v != %v", expectedFileRefs, fakeFileProvider.requestedFileNames)
	}

	// Retrieve the MojomFile for file1.
	file1, ok := descriptor.MojomFilesByName["/a/b/c/file1"]
	if !ok {
		t.Fatalf("file1 not found.")
	}

	// Check that it has 3 imports: file3, file4, file5
	if file1.Imports == nil {
		t.Fatalf("file1 has no imports.")
	}
	if len(file1.Imports) != 3 {
		t.Fatalf("len(file1.Imports)=%d", len(file1.Imports))
	}
	if file1.Imports[0].CanonicalFileName != "/a/b/c/file3" {
		t.Errorf("file1.Imports[0].CanonicalFileName=%q", file1.Imports[0].CanonicalFileName)
	}
	if file1.Imports[1].CanonicalFileName != "/a/b/c/file4" {
		t.Errorf("file1.Imports[1].CanonicalFileName=%q", file1.Imports[1].CanonicalFileName)
	}
	if file1.Imports[2].CanonicalFileName != "/a/b/c/file5" {
		t.Errorf("file1.Imports[1].CanonicalFileName=%q", file1.Imports[2].CanonicalFileName)
	}

	// Retrieve the MojomFile for file3
	file3, ok := descriptor.MojomFilesByName["/a/b/c/file3"]
	if !ok {
		t.Fatalf("file3 not found.")
	}

	// We expect the |ImportedFrom| field to be nil and the |SpecifiedFileName|
	// to be non-empty because, even though file3
	// was imported from file1, it was also a top-level file.
	if file3.ImportedFrom != nil {
		t.Errorf("file3.ImportedFrom == %v", file3.ImportedFrom)
	}
	if file3.SpecifiedFileName != "file3" {
		t.Errorf("file3.SpecifiedFileName == %v", file3.SpecifiedFileName)
	}

	// Retrieve the MojomFile for file4
	file4, ok := descriptor.MojomFilesByName["/a/b/c/file4"]
	if !ok {
		t.Fatalf("file4 not found.")
	}

	// We expect the |ImportedFrom| field to refer to file1 because file4 was imported
	// from file1 and was not a top-level file. We expect |SpecifiedFileName| to
	// be empty.
	if file4.ImportedFrom != file1 {
		t.Errorf("file4.ImportedFrom = %v", file4.ImportedFrom)
	}
	if file4.SpecifiedFileName != "" {
		t.Errorf("file4.SpecifiedFileName = %v", file4.SpecifiedFileName)
	}

}

// TestOSFileProvider tests the function OSFileProvider.findFiles() and OSFileProvider.provideContents()
func TestOSFileProvider(t *testing.T) {
	// Top level files (not imported from anything) are found relative to the current directory.
	fileReferenceA := doOSFileProviderTest(t, "../test_data/a/testfile1", nil, nil, "mojom_parser/test_data/a")
	fileReferenceB := doOSFileProviderTest(t, "../test_data/b/testfile1", nil, nil, "mojom_parser/test_data/b")

	// A file imported from a file in directory 'a' should be found in directory 'a'
	doOSFileProviderTest(t, "testfile1", &fileReferenceA, nil, "mojom_parser/test_data/a")

	// A file imported from a file in directory 'b' should be found in directory 'a'
	doOSFileProviderTest(t, "testfile1", &fileReferenceB, nil, "mojom_parser/test_data/b")

	// A file imported from a file in directory 'a' should be found in directory 'b' if there is no file with the
	// specified name in directory 'a' and directory 'b' is in the search path.
	doOSFileProviderTest(t, "testfile2", &fileReferenceA, []string{"../test_data/b"}, "mojom_parser/test_data/b")

	// The file is imported from directory 'a' and directory 'b' is on the search path but there is no file with the
	// specified name in either directory and there is a file with the specified name in the current directory.
	// The file should be found in the current directory. Note that the last argument is a random string of digits that
	// we expect to find in the contents of the file parser_driver_test.go (i.e this file).
	doOSFileProviderTest(t, "parse_driver_test.go", &fileReferenceA, []string{"../test_data/b"}, "840274941330987490326243")
}

// doOSFileProviderTest is the workhorse for TestOSFileProvider.
func doOSFileProviderTest(t *testing.T, specifiedPath string, importedFrom *FileReference,
	globalImports []string, expectedContents string) FileReference {
	fileProvider := new(OSFileProvider)
	fileProvider.importDirs = globalImports
	fileReference := FileReference{specifiedPath: specifiedPath}
	fileReference.importedFrom = importedFrom

	// Invoke findFile()
	if err := fileProvider.findFile(&fileReference); err != nil {
		t.Fatalf(err.Error())
	}

	// Check that the absolutePath has been populated to the absolute path of a file.
	if fileReference.absolutePath == "" {
		t.Fatalf("absolutePath is not set for %s", fileReference.specifiedPath)
	}
	if !filepath.IsAbs(fileReference.absolutePath) {
		t.Fatalf("absolutePath is not absolute for %s: %s", fileReference.specifiedPath, fileReference.absolutePath)
	}
	info, err := os.Stat(fileReference.absolutePath)
	if err != nil {
		t.Fatalf("cannot stat absolutePath %s: %s", fileReference.absolutePath, err.Error())
	}
	if info.IsDir() {
		t.Fatalf("absolutePath refers to a directory: %s", fileReference.absolutePath)
	}

	// Check that the dirPath has been populated to the absolute path of a directory.
	if fileReference.directoryPath == "" {
		t.Fatalf("directoryPath is not set for %s", fileReference.specifiedPath)
	}
	if !filepath.IsAbs(fileReference.directoryPath) {
		t.Fatalf("directoryPath is not absolute for %s: %s", fileReference.specifiedPath, fileReference.directoryPath)
	}
	info, err = os.Stat(fileReference.directoryPath)
	if err != nil {
		t.Fatalf("cannot stat directoryPath %s: %s", fileReference.directoryPath, err.Error())
	}
	if !info.IsDir() {
		t.Fatalf("directoryPath does not refer to a directory: %s", fileReference.directoryPath)
	}
	if filepath.Dir(fileReference.absolutePath) != fileReference.directoryPath {
		t.Fatalf("wrong directoryPath expected parent of %s got %s", fileReference.absolutePath, fileReference.directoryPath)
	}

	contents, err := fileProvider.provideContents(&fileReference)
	if err != nil {
		t.Errorf("Error from provideContents for %v: %s", fileReference, err.Error())
	}
	if !strings.Contains(contents, expectedContents) {
		t.Errorf("Wrong file contents for %v. Expecting %s got %s.", fileReference, expectedContents, contents)
	}

	return fileReference
}
