package templates

import scala.xml.Node

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

  protected[this] def templateTrade: Node = {
    <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>
          {/* executionDateTime isn`t present in the source */}
          <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>
                  {/* value isn`t present in the source */}
                  <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>
                  {/* value isn`t present in the source */}
                  <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>
                  {/* value isn`t present in the source */}
                  <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>
  }
}
