{- This file is part of irc-fun-messages.
 -
 - Written in 2015 by fr33domlover <fr33domlover@rel4tion.org>.
 -
 - ♡ Copying is an act of love. Please copy, reuse and share.
 -
 - The author(s) have dedicated all copyright and related and neighboring
 - rights to this software to the public domain worldwide. This software is
 - distributed without any warranty.
 -
 - You should have received a copy of the CC0 Public Domain Dedication along
 - with this software. If not, see
 - <http://creativecommons.org/publicdomain/zero/1.0/>.
 -}

module Network.IRC.Fun.Messages.Internal.Types
    ( -- * Type Aliases
      ServerName
    , ServiceName
    , UserName
    , NickName
    , ChannelName
    , CommandName
    , Parameter
    , Password
    , ChannelKey
    , ChannelTopic
    , RealName
    , Comment
    , PortNumber
    , Regex
      -- * Message Parts
    , Prefix (..)
    , UserAddr (..)
    , Target (..)
    , Address (..)
    , Host (..)
    , Command (..)
      -- * Mask
    , MaskPart (..)
    , Mask (..)
    , TargetMask (..)
      -- * Message
    , GenericMessage (..)
    , SpecificMessage (..)
    , MessageTarget (..)
    , Message (..)
    , AnalysisError (..)
    , ArgSpec (..)
      -- * Modes
    , UserMode (..)
    , ChannelMode (..)
    , ChannelModeType (..)
      -- * Reply
    , CommandResponseCode (..)
    , ErrorReplyCode (..)
    , ReservedReplyCode (..)
    , ReservedErrorCode (..)
    , GenericReply (..)
    , Reply (..)
    , SpecificReply (..)
    , Privilege (..)
    , ChannelPrivacy (..)
    )
where

import Text.Regex.Applicative (RE)

-------------------------------------------------------------------------------
-- Type Aliases
-------------------------------------------------------------------------------

-- | IRC server hostname, e.g. @"orwell.freenode.net"@
type ServerName = String

-- | TODO
type ServiceName = String

-- | System user name, i.e. the first part of user\@host.tld
type UserName = String

-- | IRC nickname
type NickName = String

-- | IRC channel name (including the prefix character), e.g. @"#freepost"@
type ChannelName = String

-- | IRC protocol command name, i.e. @"PRIVMSG"@
type CommandName = String

-- | IRC message parameter, e.g. second part of @JOIN #freepost@
type Parameter = String

-- | TODO
type Password = String

-- | TODO
type ChannelKey = String

-- | TODO
type ChannelTopic = String

-- | TODO
type RealName = String

-- | TODO
type Comment = String

-- | TODO
type PortNumber = Int

-- | TODO
type Regex = RE Char

-------------------------------------------------------------------------------
-- Message Parts
-------------------------------------------------------------------------------

-- | IRC message prefix.
data Prefix
    -- | The server which sends the message
    = Server ServerName
    -- | The user which sends the message (if the message comes from a user)
    | Nick NickName (Maybe UserName) (Maybe Host)
    deriving (Eq, Show)

-- | User address containing a name part (as in "user") and an optional host
-- part (as in "user@host").
data UserAddr = UserAddr UserName (Maybe Host) deriving (Eq, Show)

-- | TODO
data Target = NickTarget NickName | ServerTarget ServerName deriving (Eq, Show)

-- | An IP address.
data Address = IPv4 String | IPv6 String deriving (Eq, Show)

-- | A host, either a hostname (e.g. @irc.freenode.net@) or an IP address, or a
-- cloak assigned by the server.
data Host = HostName String | HostAddr Address | HostCloak String
    deriving (Eq, Show)

-- | TODO
data Command = StringCommand CommandName | NumericCommand Int
    deriving (Eq, Show)

-------------------------------------------------------------------------------
-- Masks
-------------------------------------------------------------------------------

-- | Part of a 'Mask'.
data MaskPart
    -- | A literal character.
    = MaskChar Char
    -- | A wildcard which matches a single character.
    | MaskWildOne
    -- | A wildcard which matches zero or more characters.
    | MaskWildMany
    deriving (Eq, Show)

-- | A pattern for matching host and server names. A mask in the protocol is a
-- string which consists of literal characters and wildcards. There are two
-- wildcards: @'?'@, which matches a single character; @'*'@, which matches any
-- number of characters (zero or more).
newtype Mask = Mask [MaskPart] deriving (Eq, Show)

-- | Some IRC command parameters are targets, and one way to specify a target
-- is using a 'Mask'.
data TargetMask
    -- | Host mask, prefixed with @'#'@ in the protocol. Selects all the users
    -- whose host matches the mask.
    = HostMask Mask
    -- | Server mask, prefixed with @'$'@ in the protocol. Selects all the
    -- users connected to a server which matches the mask.
    | ServerMask Mask
    deriving (Eq, Show)

-------------------------------------------------------------------------------
-- Message
-------------------------------------------------------------------------------

-- | A generic IRC message. It consists of a sender prefix, command name
-- (string or numeric) and optionally a list of parameters.
data GenericMessage = GenericMessage
    { gmPrefix  :: Maybe Prefix
    , gmCommand :: Command
    , gmParams  :: [Parameter]
    }
    deriving Show

-- | An IRC message of a specific type. This includes only messages whose
-- command is a name. Messages with a numeric command are handled in the
-- "Network.IRC.Fun.Messages.Reply" module.
data SpecificMessage = SpecificMessage (Maybe Prefix) Message deriving Show

-- | Some IRC commands have targets. For example, to which channel to send a
-- given text message. Targets are specified as parameters in IRC messages.
data MessageTarget
    -- | An IRC channel.
    = ChannelTarget ChannelName
    -- | An IRC user. Possible combinations in the protocol are:
    --
    -- * Address              (address host is required)
    -- * Address and server   (address host is optional)
    -- * Nickname
    -- * Nickname and address (address host is required)
    | UserTarget (Maybe NickName) (Maybe UserAddr) (Maybe ServerName)
    -- | A mask which matches the server or host of the users to whom the
    -- message should be sent.
    | MaskTarget TargetMask
    deriving Show

-- | A server query. Can be sent through a 'StatsMessage'.
data Query
    -- | TODO
    = Connections
    -- | TODO
    | CommandUsage
    -- | TODO
    | PrivilegedUsers
    -- | TODO
    | Uptime
    -- | TODO
    | OtherQuery Char
    deriving Show

-- TODO in all the either-servername-mask occurences, make sure in the RFC
-- that they are "<target> may contain wildcards" cases, and replace them with
-- plain ServerName - let's treat mask as a user mask (for bans etc.)
-- TODO in all the <target> cases, do they mean a user can be specified too,
-- to mean "the server this user is connected to"? try with some IRC servers
-- over telnet, and change ServerName to Target if yes. Note that servername
-- has '.' chars while a nickname can't, so that's how one tells which is which
-- Also compare with existing irc packages, how they model these messages

-- | An IRC message of specific type (excluding the optional sender prefix, see
-- 'SpecificMessage').
data Message
-- Connection registration
    = PassMessage Password
    | NickMessage NickName
    -- | first bool = whether invisible, second bool = whether sees wallops
    | UserMessage UserName Bool Bool RealName
    | OperMessage UserName Password
    -- | first list: modes to remove (-), second list: modes to add (+)
    | UserModeMessage NickName [UserMode] [UserMode]
    | ServiceMessage NickName Mask String
    | QuitMessage (Maybe String)
    | SQuitMessage ServerName String
-- Channel operations
    | JoinMessage (Maybe ([ChannelName], [ChannelKey]))
    | PartMessage [ChannelName] (Maybe String)
    -- first: remove (-), second: add/set (+)
    | ChannelModeMessage [ChannelMode] [ChannelMode]
    | TopicMessage ChannelName (Maybe ChannelTopic)
    | NamesMessage [ChannelName] (Maybe ServerName)
    | ListMessage [ChannelName] (Maybe ServerName)
    | InviteMessage NickName ChannelName
    | KickMessage [ChannelName] [UserName] (Maybe Comment)
-- Sending messages
    | PrivMsgMessage MessageTarget String
    | PrivActionMessage MessageTarget String
    | NoticeMessage MessageTarget String
-- Server queries and commands
    | MotdMessage (Maybe ServerName)
    | LusersMessage (Maybe (Mask, Maybe ServerName))
    | VersionMessage (Maybe (Either ServerName Mask))
    | StatsMessage (Maybe (Query, Maybe (Either ServerName Mask)))
    | LinksMessage (Maybe (Maybe (Either ServerName Mask), Mask))
    | TimeMessage (Maybe (Either ServerName Mask))
    | ConnectMessage ServerName PortNumber (Either ServerName Mask)
    | TraceMessage (Maybe Target)
    | AdminMessage (Maybe Target)
    | InfoMessage (Maybe Target)
-- Service query and commands
    | ServlistMessage (Maybe (Mask, Maybe String))
    | SQueryMessage ServiceName String
-- User based queries
    | WhoMessage (Maybe (Mask, Bool))
    | WhoisMessage (Maybe ServerName) [Mask]
    | WhowasMessage [NickName] (Maybe (Int, Maybe ServerName))
-- Miscellaneous messages
    | KillMessage NickName Comment
    | PingMessage ServerName (Maybe ServerName)
    | PongMessage ServerName (Maybe ServerName)
    | ErrorMessage String
-- Optional features
    | AwayMessage (Maybe String)
    | RehashMessage
    | DieMessage
    | RestartMessage
    | SummonMessage UserName (Maybe (ServerName, Maybe ChannelName))
    | UsersMessage (Maybe ServerName)
    | WallopsMessage String
    | UserhostMessage [NickName]
    | IsonMessage [NickName]
    deriving Show

-------------------------------------------------------------------------------
-- Modes
-------------------------------------------------------------------------------

-- | TODO
data UserMode
    -- http://toxin.jottit.com/freenode_user_modes
    = UModeInvisible
    | UModeCallerID
    | UModeSeeWallops
    | UModeDeaf
    | UModeNoForwarding
    | UModeBlockUnidentified
    | UModeConnectedViaSSL
    -- from the irc rfc, MODE message (section 3.1.5)
    | UModeAway
    | UModeRestricted
    | UModeOperator
    | UModeLocalOperator
    | UModeSeeNotices
    | UModeOther Char
    deriving (Eq, Show)

-- | TODO
data ChannelMode
    = CModeCreator
    | CModeOperator
    | CModeVoice
    | CModeAnonymous
    | CModeInviteOnly
    | CModeModerated
    | CModeNoMessagesFromOutside
    | CModeQuiet
    | CModePrivate
    | CModeSecret
    | CModeServerReop
    | CModeTopicSettableByChannelOpOnly
    | CModeKey (Maybe ChannelKey)
    | CModeUserLimit (Maybe Int)
    | CModeBanMask (Maybe Mask)
    | CModeExceptionMask (Maybe Mask)
    | CModeInvitationMask (Maybe Mask)
    | CModeOther Char [String]
    | CModeFreenodeQuiet (Maybe Mask)
    deriving (Eq, Show)

data ChannelModeType
    = ModeTypeList
    | ModeTypeSetting
    | ModeTypeMaybeSetting
    | ModeTypeFlag

-------------------------------------------------------------------------------
-- Reply
-------------------------------------------------------------------------------

-- | TODO
data CommandResponseCode
    -- | TODO
    = ReplyWelcome
    -- | TODO
    | ReplyYourHost
    -- | TODO
    | ReplyCreated
    -- | TODO
    | ReplyMyInfo
    -- | TODO
    | ReplyBounce
    -- | TODO
    | ReplyUserHost
    -- | TODO
    | ReplyIsOn
    -- | TODO
    | ReplyAway
    -- | TODO
    | ReplyUnAway
    -- | TODO
    | ReplyNoAway
    -- | TODO
    | ReplyWhoIsUser
    -- | TODO
    | ReplyWhoIsServer
    -- | TODO
    | ReplyWhoIsOperator
    -- | TODO
    | ReplyWhoIsIdle
    -- | TODO
    | ReplyEndOfWhoIs
    -- | TODO
    | ReplyWhoIsChannels
    -- | TODO
    | ReplyWhoWasUser
    -- | TODO
    | ReplyEndOfWhoWas
    -- | TODO
    | ReplyListStart
    -- | TODO
    | ReplyList
    -- | TODO
    | ReplyListEnd
    -- | TODO
    | ReplyUniqueOpIs
    -- | TODO
    | ReplyChannelModeIs
    -- | TODO
    | ReplyNoTopic
    -- | TODO
    | ReplyTopic
    -- | TODO
    | ReplyInviting
    -- | TODO
    | ReplySummoning
    -- | TODO
    | ReplyInviteList
    -- | TODO
    | ReplyEndOfInviteList
    -- | TODO
    | ReplyExceptList
    -- | TODO
    | ReplyEndOfExceptList
    -- | TODO
    | ReplyVersion
    -- | TODO
    | ReplyWhoReply
    -- | TODO
    | ReplyEndOfWho
    -- | TODO
    | ReplyNameReply
    -- | TODO
    | ReplyEndOfNames
    -- | TODO
    | ReplyLinks
    -- | TODO
    | ReplyEndOfLinks
    -- | TODO
    | ReplyBanList
    -- | TODO
    | ReplyEndOfBanList
    -- | TODO
    | ReplyInfo
    -- | TODO
    | ReplyEndOfInfo
    -- | TODO
    | ReplyMotdStart
    -- | TODO
    | ReplyMessageOfTheDay
    -- | TODO
    | ReplyEndOfMessageOfTheDay
    -- | TODO
    | ReplyYoureOper
    -- | TODO
    | ReplyRehashing
    -- | TODO
    | ReplyYoureService
    -- | TODO
    | ReplyTime
    -- | TODO
    | ReplyUsersStart
    -- | TODO
    | ReplyUsers
    -- | TODO
    | ReplyEndOfUsers
    -- | TODO
    | ReplyNoUsers
    -- | TODO
    | ReplyTraceLink
    -- | TODO
    | ReplyTraceConnecting
    -- | TODO
    | ReplyTraceHandshake
    -- | TODO
    | ReplyTraceUnknown
    -- | TODO
    | ReplyTraceOperator
    -- | TODO
    | ReplyTraceUser
    -- | TODO
    | ReplyTraceServer
    -- | TODO
    | ReplyTraceService
    -- | TODO
    | ReplyTraceNewType
    -- | TODO
    | ReplyTraceClass
    -- | TODO
    | ReplyTraceReconnect
    -- | TODO
    | ReplyTraceLog
    -- | TODO
    | ReplyTraceEnd
    -- | TODO
    | ReplyStatsLinkInfo
    -- | TODO
    | ReplyStatsCommands
    -- | TODO
    | ReplyEndOfStats
    -- | TODO
    | ReplyStatsUptime
    -- | TODO
    | ReplyStatsOLine
    -- | TODO
    | ReplyUModeIs
    -- | TODO
    | ReplyServList
    -- | TODO
    | ReplyServListEnd
    -- | TODO
    | ReplyLuserClient
    -- | TODO
    | ReplyLuserOp
    -- | TODO
    | ReplyLuserUnknown
    -- | TODO
    | ReplyLuserChannels
    -- | TODO
    | ReplyLuserMe
    -- | TODO
    | ReplyAdminMe
    -- | TODO
    | ReplyAdminLocation1
    -- | TODO
    | ReplyAdminLocation2
    -- | TODO
    | ReplyAdminEmail
    -- | TODO
    | ReplyTryAgain
    -- | TODO
    | ReplyFreenodeISupport
    deriving (Eq, Show)

data ErrorReplyCode
    -- | TODO
    = ErrorNoSuchNick
    -- | TODO
    | ErrorNoSuchServer
    -- | TODO
    | ErrorNoSuchChannel
    -- | TODO
    | ErrorCannotSendToChannel
    -- | TODO
    | ErrorTooManyChannels
    -- | TODO
    | ErrorWasNoSuchNick
    -- | TODO
    | ErrorTooManyTargets
    -- | TODO
    | ErrorNoSuchService
    -- | TODO
    | ErrorNoOrigin
    -- | TODO
    | ErrorNoRecipient
    -- | TODO
    | ErrorNoTextToSend
    -- | TODO
    | ErrorNoTopLevel
    -- | TODO
    | ErrorWildTopLevel
    -- | TODO
    | ErrorBadMask
    -- | TODO
    | ErrorUnknownCommand
    -- | TODO
    | ErrorNoMessageOfTheDay
    -- | TODO
    | ErrorNoAdminInfo
    -- | TODO
    | ErrorFileError
    -- | TODO
    | ErrorNoNickNameGiven
    -- | TODO
    | ErrorErroneousNickName
    -- | TODO
    | ErrorNickNameInUse
    -- | TODO
    | ErrorNickCollision
    -- | TODO
    | ErrorUnavailableResource
    -- | TODO
    | ErrorUserNotInChannel
    -- | TODO
    | ErrorNotOnChannel
    -- | TODO
    | ErrorUserOnChannel
    -- | TODO
    | ErrorNoLogin
    -- | TODO
    | ErrorSummonDisabled
    -- | TODO
    | ErrorUsersDisabled
    -- | TODO
    | ErrorNotRegistered
    -- | TODO
    | ErrorNeedMoreParams
    -- | TODO
    | ErrorAlreadyRegistered
    -- | TODO
    | ErrorNoPermissionForHost
    -- | TODO
    | ErrorPasswordMismatch
    -- | TODO
    | ErrorYoureBannedCreep
    -- | TODO
    | ErrorYouWillBeBanned
    -- | TODO
    | ErrorKeySet
    -- | TODO
    | ErrorChannelIsFull
    -- | TODO
    | ErrorUnknownMode
    -- | TODO
    | ErrorInviteOnlyChannel
    -- | TODO
    | ErrorBannedFromChannel
    -- | TODO
    | ErrorBadChannelKey
    -- | TODO
    | ErrorBadChannelMask
    -- | TODO
    | ErrorNoChannelModes
    -- | TODO
    | ErrorBanListFull
    -- | TODO
    | ErrorNoPrivileges
    -- | TODO
    | ErrorChannelOpPrivilegesNeeded
    -- | TODO
    | ErrorCantKillServer
    -- | TODO
    | ErrorRestricted
    -- | TODO
    | ErrorUniqueOpPrivilegesNeeded
    -- | TODO
    | ErrorNoOperHost
    -- | TODO
    | ErrorUModeUnknownFlag
    -- | TODO
    | ErrorUsersDontMatch
    deriving (Eq, Show)

data ReservedReplyCode
    -- | TODO
    = ReservedReplyServiceInfo
    -- | TODO
    | ReservedReplyEndOfServices
    -- | TODO
    | ReservedReplyService
    -- | TODO
    | ReservedReplyNone
    -- | TODO
    | ReservedReplyWhoIsChannelOp
    -- | TODO
    | ReservedReplyKillDone
    -- | TODO
    | ReservedReplyClosing
    -- | TODO
    | ReservedReplyCloseEnd
    -- | TODO
    | ReservedReplyInfoStart
    -- | TODO
    | ReservedReplyMyPortIs
    -- | TODO
    | ReservedReplyStatsCLine
    -- | TODO
    | ReservedReplyStatsNLine
    -- | TODO
    | ReservedReplyStatsILine
    -- | TODO
    | ReservedReplyStatsKLine
    -- | TODO
    | ReservedReplyStatsQLine
    -- | TODO
    | ReservedReplyStatsYLine
    -- | TODO
    | ReservedReplyStatsVLine
    -- | TODO
    | ReservedReplyStatsLLine
    -- | TODO
    | ReservedReplyStatsHLine
    -- | TODO
    | ReservedReplyStatsSLine
    -- | TODO
    | ReservedReplyStatsPing
    -- | TODO
    | ReservedReplyStatsBLine
    -- | TODO
    | ReservedReplyStatsDLine
    deriving (Eq, Show)

-- | TODO
data ReservedErrorCode
    -- | TODO
    = ReservedErrorNoServiceHost
    deriving (Eq, Show)

-- | TODO
data GenericReply = GenericReply
    { grSender :: ServerName
    , grCode   :: Int
    , grTarget :: Target
    , grParams :: [Parameter]
    }
    deriving Show

-- | TODO
data Reply
    -- | TODO
    = WelcomeReply
    -- | TODO
    | YourHostReply
    -- | TODO
    | CreatedReply
    -- | TODO
    | MyInfoReply
    -- | TODO
    | BounceReply
    -- | TODO
    | ISupportReply
    -- | TODO
    | UserHostReply
    -- | TODO
    | IsOnReply
    -- | TODO
    | AwayReply
    -- | TODO
    | UnAwayReply
    -- | TODO
    | NoAwayReply
    -- | TODO
    | WhoIsUserReply
    -- | TODO
    | WhoIsServerReply
    -- | TODO
    | WhoIsOperatorReply
    -- | TODO
    | WhoIsIdleReply
    -- | TODO
    | EndOfWhoIsReply
    -- | TODO
    | WhoIsChannelsReply
    -- | TODO
    | WhoWasUserReply
    -- | TODO
    | EndOfWhoWasReply
    -- | TODO
    | ListStartReply
    -- | TODO
    | ListReply
    -- | TODO
    | ListEndReply
    -- | TODO
    | UniqueOpIsReply
    -- | TODO
    | ChannelModeIsReply
    -- | TODO
    | NoTopicReply
    -- | TODO
    | TopicReply
    -- | TODO
    | InvitingReply
    -- | TODO
    | SummoningReply
    -- | TODO
    | InviteListReply
    -- | TODO
    | EndOfInviteListReply
    -- | TODO
    | ExceptListReply
    -- | TODO
    | EndOfExceptListReply
    -- | TODO
    | VersionReply
    -- | TODO
    | WhoReply
    -- | TODO
    | EndOfWhoReply
    -- | Lists members of IRC channels. Sent when JOINing a channel to list the
    -- users in that channel, or as a response to the NAMES command.
    | NamesReply ChannelPrivacy ChannelName [(Privilege, NickName)]
    -- | Sent after a sequence of 0 or more 'NameReply's, to signal that the
    -- list transmission is finished.
    | EndOfNamesReply
    -- | TODO
    | LinksReply
    -- | TODO
    | EndOfLinksReply
    -- | TODO
    | BanListReply
    -- | TODO
    | EndOfBanListReply
    -- | TODO
    | InfoReply
    -- | TODO
    | EndOfInfoReply
    -- | TODO
    | MotdStartReply
    -- | TODO
    | MessageOfTheDayReply
    -- | TODO
    | EndOfMessageOfTheDayReply
    -- | TODO
    | YoureOperReply
    -- | TODO
    | RehashingReply
    -- | TODO
    | YoureServiceReply
    -- | TODO
    | TimeReply
    -- | TODO
    | UsersStartReply
    -- | TODO
    | UsersReply
    -- | TODO
    | EndOfUsersReply
    -- | TODO
    | NoUsersReply
    -- | TODO
    | TraceLinkReply
    -- | TODO
    | TraceConnectingReply
    -- | TODO
    | TraceHandshakeReply
    -- | TODO
    | TraceUnknownReply
    -- | TODO
    | TraceOperatorReply
    -- | TODO
    | TraceUserReply
    -- | TODO
    | TraceServerReply
    -- | TODO
    | TraceServiceReply
    -- | TODO
    | TraceNewTypeReply
    -- | TODO
    | TraceClassReply
    -- | TODO
    | TraceReconnectReply
    -- | TODO
    | TraceLogReply
    -- | TODO
    | TraceEndReply
    -- | TODO
    | StatsLinkInfoReply
    -- | TODO
    | StatsCommandsReply
    -- | TODO
    | EndOfStatsReply
    -- | TODO
    | StatsUptimeReply
    -- | TODO
    | StatsOLineReply
    -- | TODO
    | UModeIsReply
    -- | TODO
    | ServListReply
    -- | TODO
    | ServListEndReply
    -- | TODO
    | LuserClientReply
    -- | TODO
    | LuserOpReply
    -- | TODO
    | LuserUnknownReply
    -- | TODO
    | LuserChannelsReply
    -- | TODO
    | LuserMeReply
    -- | TODO
    | AdminMeReply
    -- | TODO
    | AdminLocation1Reply
    -- | TODO
    | AdminLocation2Reply
    -- | TODO
    | AdminEmailReply
    -- | TODO
    | TryAgainReply
    deriving (Eq, Show)

-- | An IRC server numeric reply of a specific type.
data SpecificReply = SpecificReply ServerName Target Reply deriving Show

--
data Privilege = Regular | Voice | Operator deriving (Eq, Show)

--
data ChannelPrivacy = Secret | Private | Public deriving (Eq, Show)

--
data ArgSpec
    = Exactly Int
    | AtLeast Int
    | AtMost Int
    | Between Int Int
    | OneOf [Int]
    deriving (Show)

--
data AnalysisError
    = WrongNumArgs Int (Maybe ArgSpec)
    | InvalidArg (Maybe Int) (Maybe String) (Maybe String)
    | OtherError String
    deriving (Show)