package templates

import scala.xml.Node

abstract class TradeTemplate(source: Node) extends Template(source) {
  protected[this] def templateTradeBody: Node

  def template: Node = {
    <signedDocument xmlns="http://www.fpml.ru/repository">
      <document>
        <fpml:nonpublicExecutionReport xmlns:fpml="http://www.fpml.org/FpML-5/recordkeeping"
                                       xmlns:fpmlext="http://www.fpml.org/FpML-5/ext" xmlns:rtsrep="http://www.fpml.ru/repository"
                                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" fpmlVersion="5-7">
          <fpml:header>
            <fpml:messageId>{ get(source \ "header" \"messageId") }</fpml:messageId>
            <fpml:sentBy>{ get(source \ "header" \ "sentBy") }</fpml:sentBy>
            <fpml:sendTo>{ get(source \ "header" \ "sendTo") }</fpml:sendTo>
            <fpml:creationTimestamp>{ get(source \ "header" \ "creationTimestamp") }</fpml:creationTimestamp>
            <fpml:implementationSpecification>
              <fpml:version>2</fpml:version>
            </fpml:implementationSpecification>
          </fpml:header>
          <fpml:isCorrection>{ get(source \ "isCorrection") }</fpml:isCorrection>
          <fpml:correlationId correlationIdScheme="">{ get(source \ "correlationId") }</fpml:correlationId>
          <fpml:trade>
            <fpml:tradeHeader>
              { for { s <- source \ "trade" \ "tradeHeader" \ "partyTradeIdentifier"
                      id = get(s \ "partyReference", "href").mkString
                      if id != "Sender" && id != "UTIGeneratingParty" } yield {
                  <fpml:partyTradeIdentifier>
                    <fpml:partyReference href={ id }/>
                    <fpml:tradeId tradeIdScheme={ get(s \ "tradeId", "tradeIdScheme") }>{ get(s \ "tradeId") }</fpml:tradeId>
                  </fpml:partyTradeIdentifier>
                }
              }
              <fpml:partyTradeInformation>
                <fpml:partyReference href={ get(source \ "trade" \ "tradeHeader" \ "partyTradeInformation" \ "partyReference", "href") }/>
                <fpml:relatedParty>
                  <fpml:partyReference href={ get(source \ "trade" \ "tradeHeader" \ "partyTradeInformation" \ "partyReference", "href") } />
                  <fpml:role>ClearingOrganization</fpml:role>
                </fpml:relatedParty>
                <fpml:category categoryScheme="http://www.fpml.ru/repository/trade-settlement-type">{ get(source \ "trade" \ "nsdSpecificTradeFields" \ "clearSettlementType") }</fpml:category>
                <fpml:category categoryScheme="http://www.fpml.ru/repository/trade-settlement-method">{ get(source \ "trade" \ "nsdSpecificTradeFields" \ "clearSettlementMethod") }</fpml:category>
                <fpml:executionDateTime>{ get(source \ "trade" \ "tradeHeader" \ "tradeDate") + "T00:00:00" }</fpml:executionDateTime>
                <fpml:reportingRegime>
                  <fpml:name>{ get(source \ "trade" \ "tradeHeader" \ "partyTradeInformation" \ "reportingRegime" \ "name") }</fpml:name>
                  <fpml:mandatorilyClearable>{ if (get(source \ "trade" \ "nsdSpecificTradeFields" \ "cleared").mkString.contains("Y")) "true" else "" }</fpml:mandatorilyClearable>
                </fpml:reportingRegime>
              </fpml:partyTradeInformation>
              { for (s <- source \ "trade" \ "nsdSpecificTradeFields" \ "clientDetails") yield {
              <fpml:partyTradeInformation>
                <fpml:partyReference href={ get(s \ "servicingParty", "href") } />
                <fpml:relatedParty>
                  <fpml:partyReference href={ get(s \ "id") } />
                  <fpml:role>{ if (get(s \ "id").mkString != msgNotFound) "Client" else ""}</fpml:role>
                  <fpml:type>{ get(s \ "type") }</fpml:type>
                </fpml:relatedParty>
                <fpml:timestamps>
                  <fpml:timestamp>
                    <fpml:type>{ if (get(source \ "trade" \ "nsdSpecificTradeFields" \ "clearedDate").mkString != msgNotFound) "InClearingPool" else ""}</fpml:type>
                    <fpml:value>{
                      val d = get(source \ "trade" \ "nsdSpecificTradeFields" \ "clearedDate")
                      if (d.mkString != msgNotFound) d + "T00:00:00" else ""
                    }</fpml:value>
                  </fpml:timestamp>
                  <fpml:timestamp>
                    <fpml:type>{ if (get(source \ "trade" \ "nsdSpecificTradeFields" \ "startAgreementDate").mkString != msgNotFound) "InPortfolio" else ""}</fpml:type>
                    <fpml:value>{
                      val d = get(source \ "trade" \ "nsdSpecificTradeFields" \ "startAgreementDate")
                      if (d.mkString != msgNotFound) d + "T00:00:00" else ""
                    }</fpml:value>
                  </fpml:timestamp>
                  <fpml:timestamp>
                    <fpml:type>{ if (get(source \ "trade" \ "nsdSpecificTradeFields" \ "endAgreementDate").mkString != msgNotFound) "OutPortfolio" else ""}</fpml:type>
                    <fpml:value>{
                      val d = get(source \ "trade" \ "nsdSpecificTradeFields" \ "endAgreementDate")
                      if (d.mkString != msgNotFound) d + "T00:00:00" else ""
                    }</fpml:value>
                  </fpml:timestamp>
                </fpml:timestamps>
                <fpml:collateralizationType>{
                  get(source \ "trade" \ "collateral" \ "marginType").mkString match {
                    case v if v == "FC" => "Fully"
                    case v if v == "PC" => "Partially"
                    case v if v == "OC" => "OneWay"
                    case v if v == "U" => "Uncollateralized"
                    case _  => ""
                  }
                  }</fpml:collateralizationType>
                <fpml:collateralPortfolio>{ get(source \ "trade" \ "collateral" \ "collateralForm") }</fpml:collateralPortfolio>
              </fpml:partyTradeInformation>
            }
              }
            </fpml:tradeHeader>
            { templateTradeBody }
            <fpml:documentation>
              <fpml:masterAgreement>
                <fpml:masterAgreementId>{ get(source \ "trade" \ "tradeHeader" \ "partyTradeIdentifier" \ "linkId") }</fpml:masterAgreementId>
              </fpml:masterAgreement>
            </fpml:documentation>
          </fpml:trade>
          { for { s <- source \ "party"
                  id = get(s, "id").mkString
                  if id != "Sender" && id != "UTIGeneratingParty" } yield {
              <fpml:party id={ id }>
                <fpml:partyId partyIdScheme={ get(s \ "partyId", "partyIdScheme") }>{ get(s \ "partyId") }</fpml:partyId>
                <fpml:partyName>{ get(s \ "partyName") }</fpml:partyName>
                <fpml:country>{ get(s \ "country") }</fpml:country>
                <fpml:organizationType>{ get(s \ "classification") }</fpml:organizationType>
              </fpml:party>
            }
          }
          { for (s <- source \ "trade" \ "nsdSpecificTradeFields" \ "clientDetails") yield {
              <fpml:party id={ get(s \ "id") }>
                <fpml:partyId>{ get(s \ "id") }</fpml:partyId>
                <fpml:partyName>{ get(s \ "name") }</fpml:partyName>
                <fpml:country>{ get(s \ "country") }</fpml:country>
                <fpml:organizationType>{ get(s \ "classification") }</fpml:organizationType>
              </fpml:party>
            }
          }
        </fpml:nonpublicExecutionReport>
      </document>
    </signedDocument>
  }

}
