// Copyright 2017 Google Inc. All rights reserved.
//
// 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 blueprint

import (
	"fmt"
	"sort"
)

// This file exposes the logic of locating a module via a query string, to enable
// other projects to override it if desired.
// The default name resolution implementation, SimpleNameInterface,
// just treats the query string as a module name, and does a simple map lookup.

// A ModuleGroup just points to a moduleGroup to allow external packages to refer
// to a moduleGroup but not use it
type ModuleGroup struct {
	*moduleGroup
}

func (h *ModuleGroup) String() string {
	return h.moduleGroup.name
}

// The Namespace interface is just a marker interface for usage by the NameInterface,
// to allow a NameInterface to specify that a certain parameter should be a Namespace.
// In practice, a specific NameInterface will expect to only give and receive structs of
// the same concrete type, but because Go doesn't support generics, we use a marker interface
// for a little bit of clarity, and expect implementers to do typecasting instead.
type Namespace interface {
	namespace(Namespace)
}
type NamespaceMarker struct {
}

func (m *NamespaceMarker) namespace(Namespace) {
}

// A NameInterface tells how to locate modules by name.
// There should only be one name interface per Context, but potentially many namespaces
type NameInterface interface {
	// Gets called when a new module is created
	NewModule(ctx NamespaceContext, group ModuleGroup, module Module) (namespace Namespace, err []error)

	// Finds the module with the given name
	ModuleFromName(moduleName string, namespace Namespace) (group ModuleGroup, found bool)

	// Returns an error indicating that the given module could not be found.
	// The error contains some diagnostic information about where the dependency can be found.
	MissingDependencyError(depender string, dependerNamespace Namespace, depName string) (err error)

	// Rename
	Rename(oldName string, newName string, namespace Namespace) []error

	// Returns all modules in a deterministic order.
	AllModules() []ModuleGroup

	// gets the namespace for a given path
	GetNamespace(ctx NamespaceContext) (namespace Namespace)

	// returns a deterministic, unique, arbitrary string for the given name in the given namespace
	UniqueName(ctx NamespaceContext, name string) (unique string)
}

// A NamespaceContext stores the information given to a NameInterface to enable the NameInterface
// to choose the namespace for any given module
type NamespaceContext interface {
	ModulePath() string
}

type namespaceContextImpl struct {
	modulePath string
}

func newNamespaceContext(moduleInfo *moduleInfo) (ctx NamespaceContext) {
	return &namespaceContextImpl{moduleInfo.pos.Filename}
}

func (ctx *namespaceContextImpl) ModulePath() string {
	return ctx.modulePath
}

// a SimpleNameInterface just stores all modules in a map based on name
type SimpleNameInterface struct {
	modules map[string]ModuleGroup
}

func NewSimpleNameInterface() *SimpleNameInterface {
	return &SimpleNameInterface{
		modules: make(map[string]ModuleGroup),
	}
}

func (s *SimpleNameInterface) NewModule(ctx NamespaceContext, group ModuleGroup, module Module) (namespace Namespace, err []error) {
	name := group.name
	if group, present := s.modules[name]; present {
		return nil, []error{
			// seven characters at the start of the second line to align with the string "error: "
			fmt.Errorf("module %q already defined\n"+
				"       %s <-- previous definition here", name, group.modules[0].pos),
		}
	}

	s.modules[name] = group

	return nil, []error{}
}

func (s *SimpleNameInterface) ModuleFromName(moduleName string, namespace Namespace) (group ModuleGroup, found bool) {
	group, found = s.modules[moduleName]
	return group, found
}

func (s *SimpleNameInterface) Rename(oldName string, newName string, namespace Namespace) (errs []error) {
	existingGroup, exists := s.modules[newName]
	if exists {
		return []error{
			// seven characters at the start of the second line to align with the string "error: "
			fmt.Errorf("renaming module %q to %q conflicts with existing module\n"+
				"       %s <-- existing module defined here",
				oldName, newName, existingGroup.modules[0].pos),
		}
	}

	group, exists := s.modules[oldName]
	if !exists {
		return []error{fmt.Errorf("module %q to renamed to %q doesn't exist", oldName, newName)}
	}
	s.modules[newName] = group
	delete(s.modules, group.name)
	group.name = newName
	return nil
}

func (s *SimpleNameInterface) AllModules() []ModuleGroup {
	groups := make([]ModuleGroup, 0, len(s.modules))
	for _, group := range s.modules {
		groups = append(groups, group)
	}

	duplicateName := ""
	less := func(i, j int) bool {
		if groups[i].name == groups[j].name {
			duplicateName = groups[i].name
		}
		return groups[i].name < groups[j].name
	}
	sort.Slice(groups, less)
	if duplicateName != "" {
		// It is permitted to have two moduleGroup's with the same name, but not within the same
		// Namespace. The SimpleNameInterface should catch this in NewModule, however, so this
		// should never happen.
		panic(fmt.Sprintf("Duplicate moduleGroup name %q", duplicateName))
	}
	return groups
}

func (s *SimpleNameInterface) MissingDependencyError(depender string, dependerNamespace Namespace, dependency string) (err error) {
	return fmt.Errorf("%q depends on undefined module %q", depender, dependency)
}

func (s *SimpleNameInterface) GetNamespace(ctx NamespaceContext) Namespace {
	return nil
}

func (s *SimpleNameInterface) UniqueName(ctx NamespaceContext, name string) (unique string) {
	return name
}
