<commit_before>package irckit

import (
	"fmt"
	"regexp"
	"strconv"
	"strings"

	"github.com/mattermost/mattermost-server/model"
	"github.com/nlopes/slack"
	"github.com/sorcix/irc"
)

func DefaultCommands() Commands {
	cmds := commands{}

	cmds.Add(Handler{Command: irc.AWAY, Call: CmdAway, LoggedIn: true})
	cmds.Add(Handler{Command: irc.ISON, Call: CmdIson})
	cmds.Add(Handler{Command: irc.INVITE, Call: CmdInvite, LoggedIn: true, MinParams: 2})
	cmds.Add(Handler{Command: irc.JOIN, Call: CmdJoin, MinParams: 1, LoggedIn: true})
	cmds.Add(Handler{Command: irc.KICK, Call: CmdKick, MinParams: 1, LoggedIn: true})
	cmds.Add(Handler{Command: irc.LIST, Call: CmdList, LoggedIn: true})
	cmds.Add(Handler{Command: irc.LUSERS, Call: CmdLusers})
	cmds.Add(Handler{Command: irc.MODE, Call: CmdMode, MinParams: 1, LoggedIn: true})
	cmds.Add(Handler{Command: irc.MOTD, Call: CmdMotd})
	cmds.Add(Handler{Command: irc.NAMES, Call: CmdNames, MinParams: 1, LoggedIn: true})
	cmds.Add(Handler{Command: irc.NICK, Call: CmdNick, MinParams: 1})
	cmds.Add(Handler{Command: irc.PART, Call: CmdPart, MinParams: 1, LoggedIn: true})
	cmds.Add(Handler{Command: irc.PING, Call: CmdPing})
	cmds.Add(Handler{Command: irc.PRIVMSG, Call: CmdPrivMsg, MinParams: 1})
	cmds.Add(Handler{Command: irc.QUIT, Call: CmdQuit})
	cmds.Add(Handler{Command: irc.TOPIC, Call: CmdTopic, MinParams: 1, LoggedIn: true})
	cmds.Add(Handler{Command: irc.WHO, Call: CmdWho, MinParams: 1, LoggedIn: true})
	cmds.Add(Handler{Command: irc.WHOIS, Call: CmdWhois, MinParams: 1, LoggedIn: true})

	return &cmds
}

func CmdAway(s Server, u *User, msg *irc.Message) error {
	if u.mc != nil {
		u.mc.UpdateStatus(u.mc.User.Id, "online")
	}
	if u.sc != nil {
		u.sc.SetUserPresence("auto")
	}
	if msg.Trailing == "" {
		return s.EncodeMessage(u, irc.RPL_UNAWAY, []string{u.Nick}, "You are no longer marked as being away")
	}
	if u.mc != nil {
		u.mc.UpdateStatus(u.mc.User.Id, "away")
	}
	if u.sc != nil {
		u.sc.SetUserPresence("away")
	}
	return s.EncodeMessage(u, irc.RPL_NOWAWAY, []string{u.Nick}, "You have been marked as being away")
}

func CmdInvite(s Server, u *User, msg *irc.Message) error {
	who := msg.Params[0]
	channel := msg.Params[1]
	other, ok := s.HasUser(who)
	if !ok {
		return nil
	}

	if u.mc != nil {
		channelName := strings.Replace(channel, "#", "", 1)
		id := u.mc.GetChannelId(channelName, u.mc.Team.Id)
		if id == "" {
			return nil
		}
		_, resp := u.mc.Client.AddChannelMember(id, other.User)
		if resp.Error != nil {
			return resp.Error
		}
	}
	if u.sc != nil {
		if ch, exists := s.HasChannel(channel); exists {
			logger.Debugf("inviting %s to %s", other.User, strings.ToUpper(ch.ID()))
			u.sc.InviteUsersToConversation(strings.ToUpper(ch.ID()), other.User)
		}
	}

	return nil
}

// CmdIson is a handler for the /ISON command.
func CmdIson(s Server, u *User, msg *irc.Message) error {
	nicks := msg.Params
	if len(msg.Params) == 0 {
		nicks = strings.Fields(msg.Trailing)
	}
	on := make([]string, 0, len(nicks))
	for _, nick := range nicks {
		if _, ok := s.HasUser(nick); ok {
			on = append(on, nick)
		}
	}

	return u.Encode(
		&irc.Message{
			Prefix:   s.Prefix(),
			Command:  irc.RPL_ISON,
			Params:   []string{u.Nick},
			Trailing: strings.Join(on, " "),
		},
	)
}

func CmdKick(s Server, u *User, msg *irc.Message) error {
	channel := msg.Params[0]
	who := msg.Params[1]

	other, ok := s.HasUser(who)
	if !ok {
		return nil
	}
	channelName := strings.Replace(channel, "#", "", 1)
	if u.mc != nil {
		id := u.mc.GetChannelId(channelName, u.mc.Team.Id)
		if id == "" {
			return nil
		}
		_, resp := u.mc.Client.RemoveUserFromChannel(id, other.User)
		if resp.Error != nil {
			return resp.Error
		}
	}
	if u.sc != nil {
		if ch, exists := s.HasChannel(channel); exists {
			u.sc.KickUserFromConversation(strings.ToUpper(ch.ID()), other.User)
		}
	}
	return nil
}

// CmdJoin is a handler for the /JOIN command.
func CmdJoin(s Server, u *User, msg *irc.Message) error {
	var (
		channelId string
		topic     string
		sync      func(string, string)
	)

	channels := strings.Split(msg.Params[0], ",")
	for _, channel := range channels {
		channelName := strings.Replace(channel, "#", "", 1)
		// you can only join existing channels
		if u.mc != nil {
			teamId := ""
			sp := strings.Split(channelName, "/")
			if len(sp) > 1 {
				team, _ := u.mc.Client.GetTeamByName(sp[0], "")
				if team == nil {
					s.EncodeMessage(u, irc.ERR_INVITEONLYCHAN, []string{u.Nick, channel}, "Cannot join channel (+i)")
					continue
				}
				teamId = team.Id
				channelName = sp[1]
			}
			channelId = u.mc.GetChannelId(channelName, teamId)
			err := u.mc.JoinChannel(channelId)
			logger.Debugf("Join channel %s, id %s, err: %v", channelName, channelId, err)
			if err != nil {
				s.EncodeMessage(u, irc.ERR_INVITEONLYCHAN, []string{u.Nick, channel}, "Cannot join channel (+i)")
				continue
			}
			topic = u.mc.GetChannelHeader(channelId)
			sync = u.syncMMChannel
		}
		if u.sc != nil {
			//TODO: handle warnings
			mychan, _, _, err := u.sc.JoinConversation(channelName)
			if err != nil {
				s.EncodeMessage(u, irc.ERR_INVITEONLYCHAN, []string{u.Nick, channel}, "Cannot join channel (+i)")
				continue
			}
			channelId = mychan.ID
			logger.Debugf("Join channel %s, id %s, err: %v", channelName, channelId, err)
			topic = mychan.Topic.Value
			sync = u.syncSlackChannel
		}
		// if we joined, remove channel from exclude and add to include
		u.Cfg.JoinExclude = removeStringInSlice(channel, u.Cfg.JoinExclude)
		u.Cfg.JoinInclude = append(u.Cfg.JoinInclude, channel)
		ch := s.Channel(channelId)<commit_msg>Do not change JoinInclude if empty<commit_after>package irckit

import (
	"fmt"
	"regexp"
	"strconv"
	"strings"

	"github.com/mattermost/mattermost-server/model"
	"github.com/nlopes/slack"
	"github.com/sorcix/irc"
)

func DefaultCommands() Commands {
	cmds := commands{}

	cmds.Add(Handler{Command: irc.AWAY, Call: CmdAway, LoggedIn: true})
	cmds.Add(Handler{Command: irc.ISON, Call: CmdIson})
	cmds.Add(Handler{Command: irc.INVITE, Call: CmdInvite, LoggedIn: true, MinParams: 2})
	cmds.Add(Handler{Command: irc.JOIN, Call: CmdJoin, MinParams: 1, LoggedIn: true})
	cmds.Add(Handler{Command: irc.KICK, Call: CmdKick, MinParams: 1, LoggedIn: true})
	cmds.Add(Handler{Command: irc.LIST, Call: CmdList, LoggedIn: true})
	cmds.Add(Handler{Command: irc.LUSERS, Call: CmdLusers})
	cmds.Add(Handler{Command: irc.MODE, Call: CmdMode, MinParams: 1, LoggedIn: true})
	cmds.Add(Handler{Command: irc.MOTD, Call: CmdMotd})
	cmds.Add(Handler{Command: irc.NAMES, Call: CmdNames, MinParams: 1, LoggedIn: true})
	cmds.Add(Handler{Command: irc.NICK, Call: CmdNick, MinParams: 1})
	cmds.Add(Handler{Command: irc.PART, Call: CmdPart, MinParams: 1, LoggedIn: true})
	cmds.Add(Handler{Command: irc.PING, Call: CmdPing})
	cmds.Add(Handler{Command: irc.PRIVMSG, Call: CmdPrivMsg, MinParams: 1})
	cmds.Add(Handler{Command: irc.QUIT, Call: CmdQuit})
	cmds.Add(Handler{Command: irc.TOPIC, Call: CmdTopic, MinParams: 1, LoggedIn: true})
	cmds.Add(Handler{Command: irc.WHO, Call: CmdWho, MinParams: 1, LoggedIn: true})
	cmds.Add(Handler{Command: irc.WHOIS, Call: CmdWhois, MinParams: 1, LoggedIn: true})

	return &cmds
}

func CmdAway(s Server, u *User, msg *irc.Message) error {
	if u.mc != nil {
		u.mc.UpdateStatus(u.mc.User.Id, "online")
	}
	if u.sc != nil {
		u.sc.SetUserPresence("auto")
	}
	if msg.Trailing == "" {
		return s.EncodeMessage(u, irc.RPL_UNAWAY, []string{u.Nick}, "You are no longer marked as being away")
	}
	if u.mc != nil {
		u.mc.UpdateStatus(u.mc.User.Id, "away")
	}
	if u.sc != nil {
		u.sc.SetUserPresence("away")
	}
	return s.EncodeMessage(u, irc.RPL_NOWAWAY, []string{u.Nick}, "You have been marked as being away")
}

func CmdInvite(s Server, u *User, msg *irc.Message) error {
	who := msg.Params[0]
	channel := msg.Params[1]
	other, ok := s.HasUser(who)
	if !ok {
		return nil
	}

	if u.mc != nil {
		channelName := strings.Replace(channel, "#", "", 1)
		id := u.mc.GetChannelId(channelName, u.mc.Team.Id)
		if id == "" {
			return nil
		}
		_, resp := u.mc.Client.AddChannelMember(id, other.User)
		if resp.Error != nil {
			return resp.Error
		}
	}
	if u.sc != nil {
		if ch, exists := s.HasChannel(channel); exists {
			logger.Debugf("inviting %s to %s", other.User, strings.ToUpper(ch.ID()))
			u.sc.InviteUsersToConversation(strings.ToUpper(ch.ID()), other.User)
		}
	}

	return nil
}

// CmdIson is a handler for the /ISON command.
func CmdIson(s Server, u *User, msg *irc.Message) error {
	nicks := msg.Params
	if len(msg.Params) == 0 {
		nicks = strings.Fields(msg.Trailing)
	}
	on := make([]string, 0, len(nicks))
	for _, nick := range nicks {
		if _, ok := s.HasUser(nick); ok {
			on = append(on, nick)
		}
	}

	return u.Encode(
		&irc.Message{
			Prefix:   s.Prefix(),
			Command:  irc.RPL_ISON,
			Params:   []string{u.Nick},
			Trailing: strings.Join(on, " "),
		},
	)
}

func CmdKick(s Server, u *User, msg *irc.Message) error {
	channel := msg.Params[0]
	who := msg.Params[1]

	other, ok := s.HasUser(who)
	if !ok {
		return nil
	}
	channelName := strings.Replace(channel, "#", "", 1)
	if u.mc != nil {
		id := u.mc.GetChannelId(channelName, u.mc.Team.Id)
		if id == "" {
			return nil
		}
		_, resp := u.mc.Client.RemoveUserFromChannel(id, other.User)
		if resp.Error != nil {
			return resp.Error
		}
	}
	if u.sc != nil {
		if ch, exists := s.HasChannel(channel); exists {
			u.sc.KickUserFromConversation(strings.ToUpper(ch.ID()), other.User)
		}
	}
	return nil
}

// CmdJoin is a handler for the /JOIN command.
func CmdJoin(s Server, u *User, msg *irc.Message) error {
	var (
		channelId string
		topic     string
		sync      func(string, string)
	)

	channels := strings.Split(msg.Params[0], ",")
	for _, channel := range channels {
		channelName := strings.Replace(channel, "#", "", 1)
		// you can only join existing channels
		if u.mc != nil {
			teamId := ""
			sp := strings.Split(channelName, "/")
			if len(sp) > 1 {
				team, _ := u.mc.Client.GetTeamByName(sp[0], "")
				if team == nil {
					s.EncodeMessage(u, irc.ERR_INVITEONLYCHAN, []string{u.Nick, channel}, "Cannot join channel (+i)")
					continue
				}
				teamId = team.Id
				channelName = sp[1]
			}
			channelId = u.mc.GetChannelId(channelName, teamId)
			err := u.mc.JoinChannel(channelId)
			logger.Debugf("Join channel %s, id %s, err: %v", channelName, channelId, err)
			if err != nil {
				s.EncodeMessage(u, irc.ERR_INVITEONLYCHAN, []string{u.Nick, channel}, "Cannot join channel (+i)")
				continue
			}
			topic = u.mc.GetChannelHeader(channelId)
			sync = u.syncMMChannel
		}
		if u.sc != nil {
			//TODO: handle warnings
			mychan, _, _, err := u.sc.JoinConversation(channelName)
			if err != nil {
				s.EncodeMessage(u, irc.ERR_INVITEONLYCHAN, []string{u.Nick, channel}, "Cannot join channel (+i)")
				continue
			}
			channelId = mychan.ID
			logger.Debugf("Join channel %s, id %s, err: %v", channelName, channelId, err)
			topic = mychan.Topic.Value
			sync = u.syncSlackChannel
		}
		// if we joined, remove channel from exclude and add to include
		u.Cfg.JoinExclude = removeStringInSlice(channel, u.Cfg.JoinExclude)
		if len(u.Cfg.JoinInclude) > 0 {
			u.Cfg.JoinInclude = append(u.Cfg.JoinInclude, channel)
		}
		ch := s.Channel(channelId)
{'fraction_non_alphanumeric': 0.16112099644128114, 'fraction_numerical': 0.004359430604982207, 'mean_word_length': 3.761118170266836, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2112703', 'n_tokens_mistral': 4757, 'n_tokens_neox': 4389, 'n_words': 1005}