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>
        { /* Uses dictionary from PartyTemplate for identifier */ }
        <fpml:partyTradeIdentifier>
          <fpml:partyReference href={ parties("TradeRepository")._1 }/>
          <fpml:tradeId tradeIdScheme={ "UTI" }>{ get((source \\ "trade" \ "tradeHeader" \ "partyTradeIdentifier").filter(_.child.filter(_.attributes.nonEmpty).head.attributes("href").text.mkString == "UTIGeneratingParty") \ "tradeId") }</fpml:tradeId>
        </fpml:partyTradeIdentifier>
        { for { s <- source \\ "trade" \ "tradeHeader" \ "partyTradeIdentifier"
                id = get(s \ "partyReference", "href").mkString
                if id != "Sender" && id != "UTIGeneratingParty"  && id != "TradeRepository"} yield {
            <fpml:partyTradeIdentifier>
              <fpml:partyReference href={ parties(id)._1 }/>
              <fpml:tradeId tradeIdScheme={ get(s \ "tradeId", "tradeIdScheme") }>{ get(s \ "tradeId") }</fpml:tradeId>
            </fpml:partyTradeIdentifier>
          }
        }
        <fpml:partyTradeInformation>
          { /* Uses dictionary from PartyTemplate for identifier */ }
          <fpml:partyReference href={ parties(get(source \\ "trade" \ "tradeHeader" \ "partyTradeInformation" \ "partyReference", "href").mkString)._1 }/>
          <fpml:relatedParty>
            { /* Uses dictionary from PartyTemplate for identifier */ }
            <fpml:partyReference href={ parties(get(source \\ "trade" \ "tradeHeader" \ "partyTradeInformation" \ "partyReference", "href").mkString)._1 } />
            <fpml:role>ClearingOrganization</fpml:role>
          </fpml:relatedParty>
          {/* value isn`t present in the source */}
          <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>
          {/* value 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>
            {/* value isn`t present in the source. Rule from xls file */}
            <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>
              { /* Uses dictionary from PartyTemplate for identifier */ }
              <fpml:partyReference href={ parties(get(s \ "servicingParty", "href").mkString)._1 } />
              { val id = get(s \ "id").mkString
                if (id != msgNotFound)
                  <fpml:relatedParty>
                    <fpml:partyReference href={ parties(id)._1 } />
                    <fpml:role>{ "Client" }</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>
              {/* value isn`t present in the source */}
              <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>
              {/* value isn`t present in the source */}
              <fpml:collateralPortfolio>{ get(source \\ "trade" \ "collateral" \ "collateralForm") }</fpml:collateralPortfolio>
            </fpml:partyTradeInformation>
          }
        }
      </fpml:tradeHeader>
      { templateTradeBody }
      <fpml:documentation>
        <fpml:masterAgreement>
          <fpml:masterAgreementId>{
            val id = get(source \\ "trade" \ "tradeHeader" \ "partyTradeIdentifier" \ "linkId").mkString
            if (id != msgNotFound) id else "NONREF"
          }</fpml:masterAgreementId>
        </fpml:masterAgreement>
      </fpml:documentation>
    </fpml:trade>
  }
}
