// Copyright 2010 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 dict implements the Dictionary Server Protocol
// as defined in RFC 2229.
package dict // import "golang.org/x/net/dict"

import (
	"net/textproto"
	"strconv"
	"strings"
)

// A Client represents a client connection to a dictionary server.
type Client struct {
	text *textproto.Conn
}

// Dial returns a new client connected to a dictionary server at
// addr on the given network.
func Dial(network, addr string) (*Client, error) {
	text, err := textproto.Dial(network, addr)
	if err != nil {
		return nil, err
	}
	_, _, err = text.ReadCodeLine(220)
	if err != nil {
		text.Close()
		return nil, err
	}
	return &Client{text: text}, nil
}

// Close closes the connection to the dictionary server.
func (c *Client) Close() error {
	return c.text.Close()
}

// A Dict represents a dictionary available on the server.
type Dict struct {
	Name string // short name of dictionary
	Desc string // long description
}

// Dicts returns a list of the dictionaries available on the server.
func (c *Client) Dicts() ([]Dict, error) {
	id, err := c.text.Cmd("SHOW DB")
	if err != nil {
		return nil, err
	}

	c.text.StartResponse(id)
	defer c.text.EndResponse(id)

	_, _, err = c.text.ReadCodeLine(110)
	if err != nil {
		return nil, err
	}
	lines, err := c.text.ReadDotLines()
	if err != nil {
		return nil, err
	}
	_, _, err = c.text.ReadCodeLine(250)

	dicts := make([]Dict, len(lines))
	for i := range dicts {
		d := &dicts[i]
		a, _ := fields(lines[i])
		if len(a) < 2 {
			return nil, textproto.ProtocolError("invalid dictionary: " + lines[i])
		}
		d.Name = a[0]
		d.Desc = a[1]
	}
	return dicts, err
}

// A Defn represents a definition.
type Defn struct {
	Dict Dict   // Dict where definition was found
	Word string // Word being defined
	Text []byte // Definition text, typically multiple lines
}

// Define requests the definition of the given word.
// The argument dict names the dictionary to use,
// the Name field of a Dict returned by Dicts.
//
// The special dictionary name "*" means to look in all the
// server's dictionaries.
// The special dictionary name "!" means to look in all the
// server's dictionaries in turn, stopping after finding the word
// in one of them.
func (c *Client) Define(dict, word string) ([]*Defn, error) {
	id, err := c.text.Cmd("DEFINE %s %q", dict, word)
	if err != nil {
		return nil, err
	}

	c.text.StartResponse(id)
	defer c.text.EndResponse(id)

	_, line, err := c.text.ReadCodeLine(150)
	if err != nil {
		return nil, err
	}
	a, _ := fields(line)
	if len(a) < 1 {
		return nil, textproto.ProtocolError("malformed response: " + line)
	}
	n, err := strconv.Atoi(a[0])
	if err != nil {
		return nil, textproto.ProtocolError("invalid definition count: " + a[0])
	}
	def := make([]*Defn, n)
	for i := 0; i < n; i++ {
		_, line, err = c.text.ReadCodeLine(151)
		if err != nil {
			return nil, err
		}
		a, _ := fields(line)
		if len(a) < 3 {
			// skip it, to keep protocol in sync
			i--
			n--
			def = def[0:n]
			continue
		}
		d := &Defn{Word: a[0], Dict: Dict{a[1], a[2]}}
		d.Text, err = c.text.ReadDotBytes()
		if err != nil {
			return nil, err
		}
		def[i] = d
	}
	_, _, err = c.text.ReadCodeLine(250)
	return def, err
}

// Fields returns the fields in s.
// Fields are space separated unquoted words
// or quoted with single or double quote.
func fields(s string) ([]string, error) {
	var v []string
	i := 0
	for {
		for i < len(s) && (s[i] == ' ' || s[i] == '\t') {
			i++
		}
		if i >= len(s) {
			break
		}
		if s[i] == '"' || s[i] == '\'' {
			q := s[i]
			// quoted string
			var j int
			for j = i + 1; ; j++ {
				if j >= len(s) {
					return nil, textproto.ProtocolError("malformed quoted string")
				}
				if s[j] == '\\' {
					j++
					continue
				}
				if s[j] == q {
					j++
					break
				}
			}
			v = append(v, unquote(s[i+1:j-1]))
			i = j
		} else {
			// atom
			var j int
			for j = i; j < len(s); j++ {
				if s[j] == ' ' || s[j] == '\t' || s[j] == '\\' || s[j] == '"' || s[j] == '\'' {
					break
				}
			}
			v = append(v, s[i:j])
			i = j
		}
		if i < len(s) {
			c := s[i]
			if c != ' ' && c != '\t' {
				return nil, textproto.ProtocolError("quotes not on word boundaries")
			}
		}
	}
	return v, nil
}

func unquote(s string) string {
	if strings.Index(s, "\\") < 0 {
		return s
	}
	b := []byte(s)
	w := 0
	for r := 0; r < len(b); r++ {
		c := b[r]
		if c == '\\' {
			r++
			c = b[r]
		}
		b[w] = c
		w++
	}
	return string(b[0:w])
}
