// Copyright 2009 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.

// This file contains the infrastructure to create a code
// snippet for search results.
//
// Note: At the moment, this only creates HTML snippets.

package main

import (
	"bytes"
	"go/ast"
	"go/printer"
	"fmt"
	"strings"
)


type Snippet struct {
	Line int
	Text string
}


type snippetStyler struct {
	Styler               // defined in godoc.go
	highlight *ast.Ident // identifier to highlight
}


func (s *snippetStyler) LineTag(line int) (text []uint8, tag printer.HTMLTag) {
	return // no LineTag for snippets
}


func (s *snippetStyler) Ident(id *ast.Ident) (text []byte, tag printer.HTMLTag) {
	text = strings.Bytes(id.Name())
	if s.highlight == id {
		tag = printer.HTMLTag{"<span class=highlight>", "</span>"}
	}
	return
}


func newSnippet(decl ast.Decl, id *ast.Ident) *Snippet {
	var buf bytes.Buffer
	writeNode(&buf, decl, true, &snippetStyler{highlight: id})
	return &Snippet{id.Pos().Line, buf.String()}
}


func findSpec(list []ast.Spec, id *ast.Ident) ast.Spec {
	for _, spec := range list {
		switch s := spec.(type) {
		case *ast.ImportSpec:
			if s.Name == id {
				return s
			}
		case *ast.ValueSpec:
			for _, n := range s.Names {
				if n == id {
					return s
				}
			}
		case *ast.TypeSpec:
			if s.Name == id {
				return s
			}
		}
	}
	return nil
}


func genSnippet(d *ast.GenDecl, id *ast.Ident) *Snippet {
	s := findSpec(d.Specs, id)
	if s == nil {
		return nil //  declaration doesn't contain id - exit gracefully
	}

	// only use the spec containing the id for the snippet
	dd := &ast.GenDecl{d.Doc, d.Position, d.Tok, d.Lparen, []ast.Spec{s}, d.Rparen}

	return newSnippet(dd, id)
}


func funcSnippet(d *ast.FuncDecl, id *ast.Ident) *Snippet {
	if d.Name != id {
		return nil //  declaration doesn't contain id - exit gracefully
	}

	// only use the function signature for the snippet
	dd := &ast.FuncDecl{d.Doc, d.Recv, d.Name, d.Type, nil}

	return newSnippet(dd, id)
}


// NewSnippet creates a text snippet from a declaration decl containing an
// identifier id. Parts of the declaration not containing the identifier
// may be removed for a more compact snippet.
//
func NewSnippet(decl ast.Decl, id *ast.Ident) (s *Snippet) {
	switch d := decl.(type) {
	case *ast.GenDecl:
		s = genSnippet(d, id)
	case *ast.FuncDecl:
		s = funcSnippet(d, id)
	}

	// handle failure gracefully
	if s == nil {
		s = &Snippet{
			id.Pos().Line,
			fmt.Sprintf(`could not generate a snippet for <span class="highlight">%s</span>`, id.Name()),
		}
	}
	return
}
