// Copyright 2009 Thomas Jager <mail@jager.no>  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
This package provides an event based IRC client library. It allows to
register callbacks for the events you need to handle. Its features
include handling standard CTCP, reconnecting on errors and detecting
stones servers.
Details of the IRC protocol can be found in the following RFCs:
https://tools.ietf.org/html/rfc1459
https://tools.ietf.org/html/rfc2810
https://tools.ietf.org/html/rfc2811
https://tools.ietf.org/html/rfc2812
https://tools.ietf.org/html/rfc2813
The details of the client-to-client protocol (CTCP) can be found here: http://www.irchelp.org/irchelp/rfc/ctcpspec.html
*/

package irc

import (
	"bufio"
	"bytes"
	"crypto/tls"
	"errors"
	"fmt"
	"log"
	"net"
	"os"
	"strconv"
	"strings"
	"time"
)

const (
	VERSION = "go-ircevent v2.1"
)

const CAP_TIMEOUT = time.Second * 15

var ErrDisconnected = errors.New("Disconnect Called")

// Read data from a connection. To be used as a goroutine.
func (irc *Connection) readLoop() {
	defer irc.Done()
	br := bufio.NewReaderSize(irc.socket, 512)

	errChan := irc.ErrorChan()

	for {
		select {
		case <-irc.end:
			return
		default:
			// Set a read deadline based on the combined timeout and ping frequency
			// We should ALWAYS have received a response from the server within the timeout
			// after our own pings
			if irc.socket != nil {
				irc.socket.SetReadDeadline(time.Now().Add(irc.Timeout + irc.PingFreq))
			}

			msg, err := br.ReadString('\n')

			// We got past our blocking read, so bin timeout
			if irc.socket != nil {
				var zero time.Time
				irc.socket.SetReadDeadline(zero)
			}

			if err != nil {
				errChan <- err
				return
			}

			if irc.Debug {
				irc.Log.Printf("<-- %s\n", strings.TrimSpace(msg))
			}

			irc.lastMessageMutex.Lock()
			irc.lastMessage = time.Now()
			irc.lastMessageMutex.Unlock()
			event, err := parseToEvent(msg)
			if err == nil {
				event.Connection = irc
				irc.RunCallbacks(event)
			}
		}
	}
}

// Unescape tag values as defined in the IRCv3.2 message tags spec
// http://ircv3.net/specs/core/message-tags-3.2.html
func unescapeTagValue(value string) string {
	value = strings.Replace(value, "\\:", ";", -1)
	value = strings.Replace(value, "\\s", " ", -1)
	value = strings.Replace(value, "\\\\", "\\", -1)
	value = strings.Replace(value, "\\r", "\r", -1)
	value = strings.Replace(value, "\\n", "\n", -1)
	return value
}

//Parse raw irc messages
func parseToEvent(msg string) (*Event, error) {
	msg = strings.TrimSuffix(msg, "\n") //Remove \r\n
	msg = strings.TrimSuffix(msg, "\r")
	event := &Event{Raw: msg}
	if len(msg) < 5 {
		return nil, errors.New("Malformed msg from server")
	}

	if msg[0] == '@' {
		// IRCv3 Message Tags
		if i := strings.Index(msg, " "); i > -1 {
			event.Tags = make(map[string]string)
			tags := strings.Split(msg[1:i], ";")
			for _, data := range tags {
				parts := strings.SplitN(data, "=", 2)
				if len(parts) == 1 {
					event.Tags[parts[0]] = ""
				} else {
					event.Tags[parts[0]] = unescapeTagValue(parts[1])
				}
			}
			msg = msg[i+1 : len(msg)]
		} else {
			return nil, errors.New("Malformed msg from server")
		}
	}

	if msg[0] == ':' {
		if i := strings.Index(msg, " "); i > -1 {
			event.Source = msg[1:i]
			msg = msg[i+1 : len(msg)]

		} else {
			return nil, errors.New("Malformed msg from server")
		}

		if i, j := strings.Index(event.Source, "!"), strings.Index(event.Source, "@"); i > -1 && j > -1 && i < j {
			event.Nick = event.Source[0:i]
			event.User = event.Source[i+1 : j]
			event.Host = event.Source[j+1 : len(event.Source)]
		}
	}

	split := strings.SplitN(msg, " :", 2)
	args := strings.Split(split[0], " ")
	event.Code = strings.ToUpper(args[0])
	event.Arguments = args[1:]
	if len(split) > 1 {
		event.Arguments = append(event.Arguments, split[1])
	}
	return event, nil

}

// Loop to write to a connection. To be used as a goroutine.
func (irc *Connection) writeLoop() {
	defer irc.Done()
	errChan := irc.ErrorChan()
	for {
		select {
		case <-irc.end:
			return
		case b, ok := <-irc.pwrite:
			if !ok || b == "" || irc.socket == nil {
				return
			}

			if irc.Debug {
				irc.Log.Printf("--> %s\n", strings.TrimSpace(b))
			}

			// Set a write deadline based on the time out
			irc.socket.SetWriteDeadline(time.Now().Add(irc.Timeout))

			_, err := irc.socket.Write([]byte(b))

			// Past blocking write, bin timeout
			var zero time.Time
			irc.socket.SetWriteDeadline(zero)

			if err != nil {
				errChan <- err
				return
			}
		}
	}
}

// Pings the server if we have not received any messages for 5 minutes
// to keep the connection alive. To be used as a goroutine.
func (irc *Connection) pingLoop() {
	defer irc.Done()
	ticker := time.NewTicker(1 * time.Minute) // Tick every minute for monitoring
	ticker2 := time.NewTicker(irc.PingFreq)   // Tick at the ping frequency.
	for {
		select {
		case <-ticker.C:
			//Ping if we haven't received anything from the server within the keep alive period
			irc.lastMessageMutex.Lock()
			if time.Since(irc.lastMessage) >= irc.KeepAlive {
				irc.SendRawf("PING %d", time.Now().UnixNano())
			}
			irc.lastMessageMutex.Unlock()
		case <-ticker2.C:
			//Ping at the ping frequency
			irc.SendRawf("PING %d", time.Now().UnixNano())
			//Try to recapture nickname if it's not as configured.
			irc.Lock()
			if irc.nick != irc.nickcurrent {
				irc.nickcurrent = irc.nick
				irc.SendRawf("NICK %s", irc.nick)
			}
			irc.Unlock()
		case <-irc.end:
			ticker.Stop()
			ticker2.Stop()
			return
		}
	}
}

func (irc *Connection) isQuitting() bool {
	irc.Lock()
	defer irc.Unlock()
	return irc.quit
}

// Main loop to control the connection.
func (irc *Connection) Loop() {
	errChan := irc.ErrorChan()
	for !irc.isQuitting() {
		err := <-errChan
		if irc.end != nil {
			close(irc.end)
		}
		irc.Wait()
		for !irc.isQuitting() {
			irc.Log.Printf("Error, disconnected: %s\n", err)
			if err = irc.Reconnect(); err != nil {
				irc.Log.Printf("Error while reconnecting: %s\n", err)
				time.Sleep(60 * time.Second)
			} else {
				errChan = irc.ErrorChan()
				break
			}
		}
	}
}

// Quit the current connection and disconnect from the server
// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.1.6
func (irc *Connection) Quit() {
	quit := "QUIT"

	if irc.QuitMessage != "" {
		quit = fmt.Sprintf("QUIT :%s", irc.QuitMessage)
	}

	irc.SendRaw(quit)
	irc.Lock()
	irc.stopped = true
	irc.quit = true
	irc.Unlock()
}

// Use the connection to join a given channel.
// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.2.1
func (irc *Connection) Join(channel string) {
	irc.pwrite <- fmt.Sprintf("JOIN %s\r\n", channel)
}

// Leave a given channel.
// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.2.2
func (irc *Connection) Part(channel string) {
	irc.pwrite <- fmt.Sprintf("PART %s\r\n", channel)
}

// Send a notification to a nickname. This is similar to Privmsg but must not receive replies.
// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.4.2
func (irc *Connection) Notice(target, message string) {
	irc.pwrite <- fmt.Sprintf("NOTICE %s :%s\r\n", target, message)
}

// Send a formated notification to a nickname.
// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.4.2
func (irc *Connection) Noticef(target, format string, a ...interface{}) {
	irc.Notice(target, fmt.Sprintf(format, a...))
}

// Send (action) message to a target (channel or nickname).
// No clear RFC on this one...
func (irc *Connection) Action(target, message string) {
	irc.pwrite <- fmt.Sprintf("PRIVMSG %s :\001ACTION %s\001\r\n", target, message)
}

// Send formatted (action) message to a target (channel or nickname).
func (irc *Connection) Actionf(target, format string, a ...interface{}) {
	irc.Action(target, fmt.Sprintf(format, a...))
}

// Send (private) message to a target (channel or nickname).
// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.4.1
func (irc *Connection) Privmsg(target, message string) {
	irc.pwrite <- fmt.Sprintf("PRIVMSG %s :%s\r\n", target, message)
}

// Send formated string to specified target (channel or nickname).
func (irc *Connection) Privmsgf(target, format string, a ...interface{}) {
	irc.Privmsg(target, fmt.Sprintf(format, a...))
}

// Kick <user> from <channel> with <msg>. For no message, pass empty string ("")
func (irc *Connection) Kick(user, channel, msg string) {
	var cmd bytes.Buffer
	cmd.WriteString(fmt.Sprintf("KICK %s %s", channel, user))
	if msg != "" {
		cmd.WriteString(fmt.Sprintf(" :%s", msg))
	}
	cmd.WriteString("\r\n")
	irc.pwrite <- cmd.String()
}

// Kick all <users> from <channel> with <msg>. For no message, pass
// empty string ("")
func (irc *Connection) MultiKick(users []string, channel string, msg string) {
	var cmd bytes.Buffer
	cmd.WriteString(fmt.Sprintf("KICK %s %s", channel, strings.Join(users, ",")))
	if msg != "" {
		cmd.WriteString(fmt.Sprintf(" :%s", msg))
	}
	cmd.WriteString("\r\n")
	irc.pwrite <- cmd.String()
}

// Send raw string.
func (irc *Connection) SendRaw(message string) {
	irc.pwrite <- message + "\r\n"
}

// Send raw formated string.
func (irc *Connection) SendRawf(format string, a ...interface{}) {
	irc.SendRaw(fmt.Sprintf(format, a...))
}

// Set (new) nickname.
// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.1.2
func (irc *Connection) Nick(n string) {
	irc.nick = n
	irc.SendRawf("NICK %s", n)
}

// Determine nick currently used with the connection.
func (irc *Connection) GetNick() string {
	return irc.nickcurrent
}

// Query information about a particular nickname.
// RFC 1459: https://tools.ietf.org/html/rfc1459#section-4.5.2
func (irc *Connection) Whois(nick string) {
	irc.SendRawf("WHOIS %s", nick)
}

// Query information about a given nickname in the server.
// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.5.1
func (irc *Connection) Who(nick string) {
	irc.SendRawf("WHO %s", nick)
}

// Set different modes for a target (channel or nickname).
// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.2.3
func (irc *Connection) Mode(target string, modestring ...string) {
	if len(modestring) > 0 {
		mode := strings.Join(modestring, " ")
		irc.SendRawf("MODE %s %s", target, mode)
		return
	}
	irc.SendRawf("MODE %s", target)
}

func (irc *Connection) ErrorChan() chan error {
	return irc.Error
}

// Returns true if the connection is connected to an IRC server.
func (irc *Connection) Connected() bool {
	return !irc.stopped
}

// A disconnect sends all buffered messages (if possible),
// stops all goroutines and then closes the socket.
func (irc *Connection) Disconnect() {
	irc.Lock()
	defer irc.Unlock()

	if irc.end != nil {
		close(irc.end)
	}

	irc.Wait()

	irc.end = nil

	if irc.pwrite != nil {
		close(irc.pwrite)
	}

	if irc.socket != nil {
		irc.socket.Close()
	}
	irc.ErrorChan() <- ErrDisconnected
}

// Reconnect to a server using the current connection.
func (irc *Connection) Reconnect() error {
	irc.end = make(chan struct{})
	return irc.Connect(irc.Server)
}

// Connect to a given server using the current connection configuration.
// This function also takes care of identification if a password is provided.
// RFC 1459 details: https://tools.ietf.org/html/rfc1459#section-4.1
func (irc *Connection) Connect(server string) error {
	irc.Server = server
	// mark Server as stopped since there can be an error during connect
	irc.stopped = true

	// make sure everything is ready for connection
	if len(irc.Server) == 0 {
		return errors.New("empty 'server'")
	}
	if strings.Index(irc.Server, ":") == 0 {
		return errors.New("hostname is missing")
	}
	if strings.Index(irc.Server, ":") == len(irc.Server)-1 {
		return errors.New("port missing")
	}
	_, ports, err := net.SplitHostPort(irc.Server)
	if err != nil {
		return errors.New("wrong address string")
	}
	port, err := strconv.Atoi(ports)
	if err != nil {
		return errors.New("extracting port failed")
	}
	if !((port >= 0) && (port <= 65535)) {
		return errors.New("port number outside valid range")
	}
	if irc.Log == nil {
		return errors.New("'Log' points to nil")
	}
	if len(irc.nick) == 0 {
		return errors.New("empty 'nick'")
	}
	if len(irc.user) == 0 {
		return errors.New("empty 'user'")
	}

	if irc.UseTLS {
		dialer := &net.Dialer{Timeout: irc.Timeout}
		irc.socket, err = tls.DialWithDialer(dialer, "tcp", irc.Server, irc.TLSConfig)
	} else {
		irc.socket, err = net.DialTimeout("tcp", irc.Server, irc.Timeout)
	}
	if err != nil {
		return err
	}

	irc.stopped = false
	irc.Log.Printf("Connected to %s (%s)\n", irc.Server, irc.socket.RemoteAddr())

	irc.pwrite = make(chan string, 10)
	irc.Error = make(chan error, 10)
	irc.Add(3)
	go irc.readLoop()
	go irc.writeLoop()
	go irc.pingLoop()

	if len(irc.WebIRC) > 0 {
		irc.pwrite <- fmt.Sprintf("WEBIRC %s\r\n", irc.WebIRC)
	}

	if len(irc.Password) > 0 {
		irc.pwrite <- fmt.Sprintf("PASS %s\r\n", irc.Password)
	}

	err = irc.negotiateCaps()
	if err != nil {
		return err
	}

	realname := irc.user
	if irc.RealName != "" {
		realname = irc.RealName
	}

	irc.pwrite <- fmt.Sprintf("NICK %s\r\n", irc.nick)
	irc.pwrite <- fmt.Sprintf("USER %s 0.0.0.0 0.0.0.0 :%s\r\n", irc.user, realname)
	return nil
}

// Negotiate IRCv3 capabilities
func (irc *Connection) negotiateCaps() error {
	saslResChan := make(chan *SASLResult)
	if irc.UseSASL {
		irc.RequestCaps = append(irc.RequestCaps, "sasl")
		irc.setupSASLCallbacks(saslResChan)
	}

	if len(irc.RequestCaps) == 0 {
		return nil
	}

	cap_chan := make(chan bool, len(irc.RequestCaps))
	irc.AddCallback("CAP", func(e *Event) {
		if len(e.Arguments) != 3 {
			return
		}
		command := e.Arguments[1]

		if command == "LS" {
			missing_caps := len(irc.RequestCaps)
			for _, cap_name := range strings.Split(e.Arguments[2], " ") {
				for _, req_cap := range irc.RequestCaps {
					if cap_name == req_cap {
						irc.pwrite <- fmt.Sprintf("CAP REQ :%s\r\n", cap_name)
						missing_caps--
					}
				}
			}

			for i := 0; i < missing_caps; i++ {
				cap_chan <- true
			}
		} else if command == "ACK" || command == "NAK" {
			for _, cap_name := range strings.Split(strings.TrimSpace(e.Arguments[2]), " ") {
				if cap_name == "" {
					continue
				}

				if command == "ACK" {
					irc.AcknowledgedCaps = append(irc.AcknowledgedCaps, cap_name)
				}
				cap_chan <- true
			}
		}
	})

	irc.pwrite <- "CAP LS\r\n"

	if irc.UseSASL {
		select {
		case res := <-saslResChan:
			if res.Failed {
				close(saslResChan)
				return res.Err
			}
		case <-time.After(CAP_TIMEOUT):
			close(saslResChan)
			// Raise an error if we can't authenticate with SASL.
			return errors.New("SASL setup timed out. Does the server support SASL?")
		}
	}

	remaining_caps := len(irc.RequestCaps)

	select {
	case <-cap_chan:
		remaining_caps--
	case <-time.After(CAP_TIMEOUT):
		// The server probably doesn't implement CAP LS, which is "normal".
		return nil
	}

	// Wait for all capabilities to be ACKed or NAKed before ending negotiation
	for remaining_caps > 0 {
		<-cap_chan
		remaining_caps--
	}

	irc.pwrite <- fmt.Sprintf("CAP END\r\n")

	return nil
}

// Create a connection with the (publicly visible) nickname and username.
// The nickname is later used to address the user. Returns nil if nick
// or user are empty.
func IRC(nick, user string) *Connection {
	// catch invalid values
	if len(nick) == 0 {
		return nil
	}
	if len(user) == 0 {
		return nil
	}

	irc := &Connection{
		nick:        nick,
		nickcurrent: nick,
		user:        user,
		Log:         log.New(os.Stdout, "", log.LstdFlags),
		end:         make(chan struct{}),
		Version:     VERSION,
		KeepAlive:   4 * time.Minute,
		Timeout:     1 * time.Minute,
		PingFreq:    15 * time.Minute,
		SASLMech:    "PLAIN",
		QuitMessage: "",
	}
	irc.setupCallbacks()
	return irc
}
