// Copyright 2020 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 state_test

import (
	"testing"

	fidlcommon "fidl-lsp/third_party/common"

	"fidl-lsp/state"
)

func TestLibraryOfFile(t *testing.T) {
	library, err := state.LibraryOfFile(`library example;`)
	if err != nil {
		t.Errorf("error getting library of file: %s", err)
	}
	expLibrary := "example"
	if library.FullyQualifiedName() != expLibrary {
		t.Errorf("expected library `%s`, got `%s`", expLibrary, library)
	}

	library, err = state.LibraryOfFile(`
/// Doc comments
library fuchsia.foo.bar;
struct S {};
`)
	if err != nil {
		t.Errorf("error getting library of file: %s", err)
	}
	expLibrary = "fuchsia.foo.bar"
	if library.FullyQualifiedName() != expLibrary {
		t.Errorf("expected library `%s`, got `%s`", expLibrary, library)
	}

	library, err = state.LibraryOfFile(`library .invalid.name;`)
	if err == nil {
		t.Error("expect error getting library of file")
	}

	library, err = state.LibraryOfFile(`library exampl // Missing semicolon`)
	if err == nil {
		t.Error("expect error getting library of file")
	}
}

func TestParseLibraryMatch(t *testing.T) {
	library, ok := state.ParseLibraryMatch(`
library example;
//      ~~~~~~~ expected range
`)
	if !ok {
		t.Errorf("error getting library of file")
	}
	expLibrary := state.LibraryMatch{
		Lib: fidlcommon.MustReadLibraryName("example"),
		Range: state.Range{
			Start: state.Position{Line: 1, Character: 8},
			End:   state.Position{Line: 1, Character: 15},
		},
	}
	if library != expLibrary {
		t.Errorf("expected library `%v`, got `%v`", expLibrary, library)
	}

	library, ok = state.ParseLibraryMatch(`
/// Doc comments
library fuchsia.foo.bar;
//      ~~~~~~~~~~~~~~~ expected range
struct S {};
`)
	if !ok {
		t.Errorf("error getting library of file")
	}
	expLibrary = state.LibraryMatch{
		Lib: fidlcommon.MustReadLibraryName("fuchsia.foo.bar"),
		Range: state.Range{
			Start: state.Position{Line: 2, Character: 8},
			End:   state.Position{Line: 2, Character: 23},
		},
	}
	if library != expLibrary {
		t.Errorf("expected library `%v`, got `%v`", expLibrary, library)
	}

	library, ok = state.ParseLibraryMatch(`library .invalid.name;`)
	if ok {
		t.Error("expect error getting library of file")
	}

	library, ok = state.ParseLibraryMatch(`library exampl // Missing semicolon`)
	if ok {
		t.Error("expect error getting library of file")
	}
}

func TestParsePlatformImportsMatch(t *testing.T) {
	imports := state.ParsePlatformImportsMatch(`
library example;
using fuchsia.foo.bar;
using fuchsia.baz.qux;
using non.platform.import;
using TypeAlias = uint8;
`)

	expImports := []state.LibraryMatch{
		{
			Lib: fidlcommon.MustReadLibraryName("fuchsia.foo.bar"),
			Range: state.Range{
				Start: state.Position{Line: 2, Character: 6},
				End:   state.Position{Line: 2, Character: 21},
			},
		},
		{
			Lib: fidlcommon.MustReadLibraryName("fuchsia.baz.qux"),
			Range: state.Range{
				Start: state.Position{Line: 3, Character: 6},
				End:   state.Position{Line: 3, Character: 21},
			},
		},
	}
	if len(imports) != len(expImports) {
		t.Errorf("expected %d imports, found %d", len(expImports), len(imports))
	}
	for i, expImport := range expImports {
		if imports[i] != expImport {
			t.Errorf("unexpected import `%v`, expected `%v`", imports[i], expImport)
		}
	}
}

func TestSymbolAtPos(t *testing.T) {
	fs := state.NewFileSystem()
	fs.NewFile("test.fidl", `
library example;
using test.import;

struct Foo {
    uint8 bar_baz;
};
`)

	cases := []struct {
		pos state.Position
		sym state.Symbol
	}{
		{
			pos: state.Position{Line: 1, Character: 0},
			sym: state.Symbol{
				Name: "library",
				Location: state.Location{
					FileID: state.FileID("test.fidl"),
					Range: state.Range{
						Start: state.Position{Line: 1, Character: 0},
						End:   state.Position{Line: 1, Character: 7},
					},
				},
			},
		},
		{
			pos: state.Position{Line: 1, Character: 15},
			sym: state.Symbol{
				Name: "example",
				Location: state.Location{
					FileID: state.FileID("test.fidl"),
					Range: state.Range{
						Start: state.Position{Line: 1, Character: 8},
						End:   state.Position{Line: 1, Character: 15},
					},
				},
			},
		},
		{
			pos: state.Position{Line: 2, Character: 11},
			sym: state.Symbol{
				Name: "test.import",
				Location: state.Location{
					FileID: state.FileID("test.fidl"),
					Range: state.Range{
						Start: state.Position{Line: 2, Character: 6},
						End:   state.Position{Line: 2, Character: 17},
					},
				},
			},
		},
		{
			pos: state.Position{Line: 4, Character: 10},
			sym: state.Symbol{
				Name: "Foo",
				Location: state.Location{
					FileID: state.FileID("test.fidl"),
					Range: state.Range{
						Start: state.Position{Line: 4, Character: 7},
						End:   state.Position{Line: 4, Character: 10},
					},
				},
			},
		},
		{
			pos: state.Position{Line: 5, Character: 13},
			sym: state.Symbol{
				Name: "bar_baz",
				Location: state.Location{
					FileID: state.FileID("test.fidl"),
					Range: state.Range{
						Start: state.Position{Line: 5, Character: 10},
						End:   state.Position{Line: 5, Character: 17},
					},
				},
			},
		},
	}

	for _, ex := range cases {
		sym, err := fs.SymbolAtPos(
			state.FileID("test.fidl"),
			ex.pos,
		)
		if err != nil {
			t.Fatalf("error finding symbol: %s", err)
		}
		if sym.Name != ex.sym.Name {
			t.Fatalf("did not find correct symbol; expected %s, found %s", ex.sym.Name, sym.Name)
		}
		if sym.Location.FileID != ex.sym.Location.FileID {
			t.Fatalf(
				"incorrect file; expected %s, found %s",
				ex.sym.Location.FileID,
				sym.Location.FileID,
			)
		}
		if sym.Location.Range != ex.sym.Location.Range {
			t.Fatalf(
				"incorrect range; expected %#v, found %#v",
				ex.sym.Location.Range,
				sym.Location.Range,
			)
		}
	}
}

func TestNoSymbolAtPos(t *testing.T) {
	fs := state.NewFileSystem()
	fs.NewFile("test.fidl", `
//							 ^ should not be a symbol
library example;
//			   ^ should not be a symbol

struct Foo {
//		   ^ should not be a symbol
    uint8 foo;
//^ should not be a symbol
};

.prepended.dot
^ should not be a symbol ('prepended.dot' is a valid symbol)
trailing.dot.
			^ should not be a symbol  ('trailing.dot' is a valid symbol)
0starts_with_a_number
	^ should not be a symbol
ends_with_a_semicolon_
	^ should not be a symbol
`)

	cases := []state.Position{
		{Line: 0, Character: 0},
		{Line: 2, Character: 16},
		{Line: 5, Character: 11},
		{Line: 7, Character: 2},
		{Line: 11, Character: 0},
		{Line: 13, Character: 13},
		{Line: 15, Character: 3},
		{Line: 17, Character: 3},
	}

	for _, ex := range cases {
		sym, err := fs.SymbolAtPos(
			state.FileID("test.fidl"),
			ex,
		)
		if err == nil {
			t.Errorf("expected not to find symbol at position %v, but found %s", ex, sym.Name)
		}
	}
}
