package templates

import scala.xml.Node

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

  def template: Node = {
    <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 msgNotFound }</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 msgNotFound}</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 msgNotFound}</fpml:type>
                    <fpml:value>{
                      val d = get(source \ "trade" \ "nsdSpecificTradeFields" \ "clearedDate")
                      if (d.mkString != msgNotFound) d + "T00:00:00" else msgNotFound
                    }</fpml:value>
                  </fpml:timestamp>
                  <fpml:timestamp>
                    <fpml:type>{ if (get(source \ "trade" \ "nsdSpecificTradeFields" \ "startAgreementDate").mkString != msgNotFound) "InPortfolio" else msgNotFound}</fpml:type>
                    <fpml:value>{
                      val d = get(source \ "trade" \ "nsdSpecificTradeFields" \ "startAgreementDate")
                      if (d.mkString != msgNotFound) d + "T00:00:00" else msgNotFound
                    }</fpml:value>
                  </fpml:timestamp>
                  <fpml:timestamp>
                    <fpml:type>{ if (get(source \ "trade" \ "nsdSpecificTradeFields" \ "endAgreementDate").mkString != msgNotFound) "OutPortfolio" else msgNotFound}</fpml:type>
                    <fpml:value>{
                      val d = get(source \ "trade" \ "nsdSpecificTradeFields" \ "endAgreementDate")
                      if (d.mkString != msgNotFound) d + "T00:00:00" else msgNotFound
                    }</fpml:value>
                  </fpml:timestamp>
                </fpml:timestamps>
                <fpml:collateralizationType>{
                  get(source \ "trade" \ "collateral" \ "marginType").mkString match {
                    case "FC" => "Fully"
                    case "PC" => "Partially"
                    case "OC" => "OneWay"
                    case "U" => "Uncollateralized"
                    case _  => msgNotFound
                  }
                }</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>
  }
}
