// Copyright 2019 The Go 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 lsp

import (
	"context"
	"fmt"
	"os"
	"path/filepath"
	"sync/atomic"

	"golang.org/x/tools/internal/event"
	"golang.org/x/tools/internal/lsp/protocol"
	"golang.org/x/tools/internal/lsp/source"
	"golang.org/x/tools/internal/span"
	errors "golang.org/x/xerrors"
)

func (s *Server) didChangeWorkspaceFolders(ctx context.Context, params *protocol.DidChangeWorkspaceFoldersParams) error {
	event := params.Event
	for _, folder := range event.Removed {
		view := s.session.View(folder.Name)
		if view != nil {
			view.Shutdown(ctx)
		} else {
			return errors.Errorf("view %s for %v not found", folder.Name, folder.URI)
		}
	}
	return s.addFolders(ctx, event.Added)
}

var wsIndex int64

func (s *Server) addView(ctx context.Context, name string, uri span.URI) (source.Snapshot, func(), error) {
	s.stateMu.Lock()
	state := s.state
	s.stateMu.Unlock()
	if state < serverInitialized {
		return nil, func() {}, errors.Errorf("addView called before server initialized")
	}
	options := s.session.Options().Clone()
	if err := s.fetchConfig(ctx, name, uri, options); err != nil {
		return nil, func() {}, err
	}
	// Try to assign a persistent temp directory for tracking this view's
	// temporary workspace.
	var tempWorkspace span.URI
	if s.tempDir != "" {
		index := atomic.AddInt64(&wsIndex, 1)
		wsDir := filepath.Join(s.tempDir, fmt.Sprintf("workspace.%d", index))
		if err := os.Mkdir(wsDir, 0700); err == nil {
			tempWorkspace = span.URIFromPath(wsDir)
		} else {
			event.Error(ctx, "making workspace dir", err)
		}
	}
	_, snapshot, release, err := s.session.NewView(ctx, name, uri, tempWorkspace, options)
	return snapshot, release, err
}

func (s *Server) didChangeConfiguration(ctx context.Context, _ *protocol.DidChangeConfigurationParams) error {
	// Apply any changes to the session-level settings.
	options := s.session.Options().Clone()
	semanticTokensRegistered := options.SemanticTokens
	if err := s.fetchConfig(ctx, "", "", options); err != nil {
		return err
	}
	s.session.SetOptions(options)

	// Go through each view, getting and updating its configuration.
	for _, view := range s.session.Views() {
		options := s.session.Options().Clone()
		if err := s.fetchConfig(ctx, view.Name(), view.Folder(), options); err != nil {
			return err
		}
		view, err := view.SetOptions(ctx, options)
		if err != nil {
			return err
		}
		go func() {
			snapshot, release := view.Snapshot(ctx)
			defer release()
			s.diagnoseDetached(snapshot)
		}()
	}

	// Update any session-specific registrations or unregistrations.
	if !semanticTokensRegistered && options.SemanticTokens {
		if err := s.client.RegisterCapability(ctx, &protocol.RegistrationParams{
			Registrations: []protocol.Registration{semanticTokenRegistration()},
		}); err != nil {
			return err
		}
	} else if semanticTokensRegistered && !options.SemanticTokens {
		if err := s.client.UnregisterCapability(ctx, &protocol.UnregistrationParams{
			Unregisterations: []protocol.Unregistration{
				{
					ID:     semanticTokenRegistration().ID,
					Method: semanticTokenRegistration().Method,
				},
			},
		}); err != nil {
			return err
		}
	}
	return nil
}

func semanticTokenRegistration() protocol.Registration {
	return protocol.Registration{
		ID:     "textDocument/semanticTokens",
		Method: "textDocument/semanticTokens",
		RegisterOptions: &protocol.SemanticTokensOptions{
			Legend: protocol.SemanticTokensLegend{
				// TODO(pjw): trim these to what we use (and an unused one
				// at position 0 of TokTypes, to catch typos)
				TokenTypes:     SemanticTypes(),
				TokenModifiers: SemanticModifiers(),
			},
			Full:  true,
			Range: true,
		},
	}
}
