using System ;
using MediaBrowser.Dlna.Common ;
using System.Collections.Generic ;
using System.Linq ;
using System.Xml.Linq ;
using MediaBrowser.Dlna.Ssdp ;
namespace MediaBrowser.Dlna.PlayTo
{
public class TransportCommands
{
private List < StateVariable > _stateVariables = new List < StateVariable > ( ) ;
public List < StateVariable > StateVariables
{
get
{
return _stateVariables ;
}
set
{
_stateVariables = value ;
}
}
private List < ServiceAction > _serviceActions = new List < ServiceAction > ( ) ;
public List < ServiceAction > ServiceActions
{
get
{
return _serviceActions ;
}
set
{
_serviceActions = value ;
}
}
public static TransportCommands Create ( XDocument document )
{
var command = new TransportCommands ( ) ;
var actionList = document . Descendants ( uPnpNamespaces . svc + "actionList" ) ;
foreach ( var container in actionList . Descendants ( uPnpNamespaces . svc + "action" ) )
{
command . ServiceActions . Add ( ServiceActionFromXml ( container ) ) ;
}
var stateValues = document . Descendants ( uPnpNamespaces . ServiceStateTable ) . FirstOrDefault ( ) ;
if ( stateValues ! = null )
{
foreach ( var container in stateValues . Elements ( uPnpNamespaces . svc + "stateVariable" ) )
{
command . StateVariables . Add ( FromXml ( container ) ) ;
}
}
return command ;
}
private static ServiceAction ServiceActionFromXml ( XElement container )
{
var argumentList = new List < Argument > ( ) ;
foreach ( var arg in container . Descendants ( uPnpNamespaces . svc + "argument" ) )
{
argumentList . Add ( ArgumentFromXml ( arg ) ) ;
}
return new ServiceAction
{
Name = container . GetValue ( uPnpNamespaces . svc + "name" ) ,
ArgumentList = argumentList
} ;
}
private static Argument ArgumentFromXml ( XElement container )
{
if ( container = = null )
{
throw new ArgumentNullException ( "container" ) ;
}
return new Argument
{
Name = container . GetValue ( uPnpNamespaces . svc + "name" ) ,
Direction = container . GetValue ( uPnpNamespaces . svc + "direction" ) ,
RelatedStateVariable = container . GetValue ( uPnpNamespaces . svc + "relatedStateVariable" )
} ;
}
public static StateVariable FromXml ( XElement container )
{
var allowedValues = new List < string > ( ) ;
var element = container . Descendants ( uPnpNamespaces . svc + "allowedValueList" )
. FirstOrDefault ( ) ;
if ( element ! = null )
{
var values = element . Descendants ( uPnpNamespaces . svc + "allowedValue" ) ;
allowedValues . AddRange ( values . Select ( child = > child . Value ) ) ;
}
return new StateVariable
{
Name = container . GetValue ( uPnpNamespaces . svc + "name" ) ,
DataType = container . GetValue ( uPnpNamespaces . svc + "dataType" ) ,
AllowedValues = allowedValues
} ;
}
public string BuildPost ( ServiceAction action , string xmlNamespace )
{
var stateString = string . Empty ;
foreach ( var arg in action . ArgumentList )
{
if ( arg . Direction = = "out" )
continue ;
if ( arg . Name = = "InstanceID" )
stateString + = BuildArgumentXml ( arg , "0" ) ;
else
stateString + = BuildArgumentXml ( arg , null ) ;
}
return string . Format ( CommandBase , action . Name , xmlNamespace , stateString ) ;
}
public string BuildPost ( ServiceAction action , string xmlNamesapce , object value , string commandParameter = "" )
{
var stateString = string . Empty ;
foreach ( var arg in action . ArgumentList )
{
if ( arg . Direction = = "out" )
continue ;
if ( arg . Name = = "InstanceID" )
stateString + = BuildArgumentXml ( arg , "0" ) ;
else
stateString + = BuildArgumentXml ( arg , value . ToString ( ) , commandParameter ) ;
}
return string . Format ( CommandBase , action . Name , xmlNamesapce , stateString ) ;
}
public string BuildPost ( ServiceAction action , string xmlNamesapce , object value , Dictionary < string , string > dictionary )
{
var stateString = string . Empty ;
foreach ( var arg in action . ArgumentList )
{
if ( arg . Name = = "InstanceID" )
stateString + = BuildArgumentXml ( arg , "0" ) ;
else if ( dictionary . ContainsKey ( arg . Name ) )
stateString + = BuildArgumentXml ( arg , dictionary [ arg . Name ] ) ;
else
stateString + = BuildArgumentXml ( arg , value . ToString ( ) ) ;
}
return string . Format ( CommandBase , action . Name , xmlNamesapce , stateString ) ;
}
private string BuildArgumentXml ( Argument argument , string value , string commandParameter = "" )
{
var state = StateVariables . FirstOrDefault ( a = > string . Equals ( a . Name , argument . RelatedStateVariable , StringComparison . OrdinalIgnoreCase ) ) ;
if ( state ! = null )
{
var sendValue = state . AllowedValues . FirstOrDefault ( a = > string . Equals ( a , commandParameter , StringComparison . OrdinalIgnoreCase ) ) ? ?
state . AllowedValues . FirstOrDefault ( ) ? ?
value ;
return string . Format ( "<{0} xmlns:dt=\"urn:schemas-microsoft-com:datatypes\" dt:dt=\"{1}\">{2}</{0}>" , argument . Name , state . DataType ? ? "string" , sendValue ) ;
}
return string . Format ( "<{0}>{1}</{0}>" , argument . Name , value ) ;
}
private const string CommandBase = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" + "<SOAP-ENV:Body>" + "<m:{0} xmlns:m=\"{1}\">" + "{2}" + "</m:{0}>" + "</SOAP-ENV:Body></SOAP-ENV:Envelope>" ;
}
}