content: {-# LANGUAGE CPP #-}
  {-# LANGUAGE OverloadedStrings #-}
  {-# LANGUAGE QuasiQuotes #-}
  module PivotTableTests
    ( tests
    , testPivotTable
    , testPivotSrcCells
    ) where
  
  #ifdef USE_MICROLENS
  import Lens.Micro
  #else
  import Control.Lens
  #endif
  import Data.ByteString.Lazy (ByteString)
  import qualified Data.Map as M
  import Data.Maybe (mapMaybe)
  import qualified Data.Text as T
  import Test.Tasty (testGroup, TestTree)
  import Test.Tasty.HUnit (testCase)
  import Text.RawString.QQ
  import Text.XML
  
  import Codec.Xlsx
  import Codec.Xlsx.Parser.Internal.PivotTable
  import Codec.Xlsx.Types.Internal (unsafeRefId)
  import Codec.Xlsx.Types.PivotTable.Internal
  import Codec.Xlsx.Writer.Internal.PivotTable
  
  import Diff
  
  tests :: TestTree
  tests =
    testGroup
      "Pivot table tests"
      [ testCase "proper pivot table rendering" $ do
          let ptFiles = renderPivotTableFiles testPivotSrcCells 3 testPivotTable
          parseLBS_ def (pvtfTable ptFiles) @==?
            stripContentSpaces (parseLBS_ def testPivotTableDefinition)
          parseLBS_ def (pvtfCacheDefinition ptFiles) @==?
            stripContentSpaces (parseLBS_ def testPivotCacheDefinition)
      , testCase "proper pivot table parsing" $ do
          let sheetName = "Sheet1"
              ref = CellRef "A1:D5"
              forCacheId (CacheId 3) = Just (sheetName, ref, testPivotCacheFields)
              forCacheId _ = Nothing
              -- fields with numeric values go into cache records
              testPivotCacheFields' =
                [ if cfName cf == PivotFieldName "Color"
                  then cf
                  else cf {cfItems = []}
                | cf <- testPivotCacheFields
                ]
          Just (sheetName, ref, testPivotCacheFields', Just (unsafeRefId 1)) @==?
            parseCache testPivotCacheDefinition
          Just testPivotTable @==?
            parsePivotTable forCacheId testPivotTableDefinition
      ]
  
  testPivotTable :: PivotTable
  testPivotTable =
    PivotTable
    { _pvtName = "PivotTable1"
    , _pvtDataCaption = "Values"
    , _pvtLocation = CellRef "A3:D12"
    , _pvtSrcRef = CellRef "A1:D5"
    , _pvtSrcSheet = "Sheet1"
    , _pvtRowFields = [FieldPosition colorField, DataPosition]
    , _pvtColumnFields = [FieldPosition yearField]
    , _pvtDataFields =
        [ DataField
          { _dfName = "Sum of field Price"
          , _dfField = priceField
          , _dfFunction = ConsolidateSum
          }
        , DataField
          { _dfName = "Sum of field Count"
          , _dfField = countField
          , _dfFunction = ConsolidateSum
          }
        ]
    , _pvtFields =
        [ PivotFieldInfo (Just $ colorField) False FieldSortAscending [CellText "green"]
        , PivotFieldInfo (Just $ yearField) True FieldSortManual []
        , PivotFieldInfo (Just $ priceField) False FieldSortManual []
        , PivotFieldInfo (Just $ countField) False FieldSortManual []
        ]
    , _pvtRowGrandTotals = True
    , _pvtColumnGrandTotals = False
    , _pvtOutline = False
    , _pvtOutlineData = False
    }
    where
      colorField = PivotFieldName "Color"
      yearField = PivotFieldName "Year"
      priceField = PivotFieldName "Price"
      countField = PivotFieldName "Count"
  
  testPivotSrcCells :: CellMap
  testPivotSrcCells =
    M.fromList $
    concat
      [ [((row, col), def & cellValue ?~ v) | (col, v) <- zip [1 ..] cells]
      | (row, cells) <- zip [1 ..] cellMap
      ]
    where
      cellMap =
        [ [CellText "Color", CellText "Year", CellText "Price", CellText "Count"]
        , [CellText "green", CellDouble 2012, CellDouble 12.23, CellDouble 17]
        , [CellText "white", CellDouble 2011, CellDouble 73.99, CellDouble 21]
        , [CellText "red", CellDouble 2012, CellDouble 10.19, CellDouble 172]
        , [CellText "white", CellDouble 2012, CellDouble 34.99, CellDouble 49]
        ]
  
  testPivotCacheFields :: [CacheField]
  testPivotCacheFields =
    [ CacheField
        (PivotFieldName "Color")
        [CellText "green", CellText "white", CellText "red"]
    , CacheField (PivotFieldName "Year") [CellDouble 2012, CellDouble 2011]
    , CacheField
        (PivotFieldName "Price")
        [CellDouble 12.23, CellDouble 73.99, CellDouble 10.19, CellDouble 34.99]
    , CacheField
        (PivotFieldName "Count")
        [CellDouble 17, CellDouble 21, CellDouble 172, CellDouble 49]
    ]
  
  testPivotTableDefinition :: ByteString
  testPivotTableDefinition = [r|
  <?xml version="1.0" encoding="UTF-8" standalone="yes"?><!--Pivot table generated by xlsx-->
  <pivotTableDefinition xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" name="PivotTable1" cacheId="3" dataOnRows="1" colGrandTotals="0" dataCaption="Values">
    <location ref="A3:D12" firstHeaderRow="1" firstDataRow="2" firstDataCol="1"/>
    <pivotFields>
      <pivotField name="Color" axis="axisRow" showAll="0" outline="0" sortType="ascending">
        <items>
          <item h="1" x="0"/><item x="1"/><item x="2"/><item t="default"/>
        </items>
      </pivotField>
      <pivotField name="Year" axis="axisCol" showAll="0" outline="1">
        <items>
          <item x="0"/><item x="1"/><item t="default"/>
        </items>
      </pivotField>
      <pivotField name="Price" dataField="1" showAll="0" outline="0"/>
      <pivotField name="Count" dataField="1" showAll="0" outline="0"/>
   </pivotFields>
    <rowFields><field x="0"/><field x="-2"/></rowFields>
    <colFields><field x="1"/></colFields>
    <dataFields>
      <dataField name="Sum of field Price" fld="2"/>
      <dataField name="Sum of field Count" fld="3"/>
    </dataFields>
  </pivotTableDefinition>
  |]
  
  testPivotCacheDefinition :: ByteString
  testPivotCacheDefinition = [r|
  <?xml version="1.0" encoding="UTF-8" standalone="yes"?><!--Pivot cache definition generated by xlsx-->
  <pivotCacheDefinition xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
      xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId1"
      invalid="1" refreshOnLoad="1"
      xmlns:ns="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
    <cacheSource type="worksheet">
      <worksheetSource ref="A1:D5" sheet="Sheet1"/>
    </cacheSource>
    <cacheFields>
      <cacheField name="Color">
       <sharedItems>
         <s v="green"/><s v="white"/><s v="red"/>
       </sharedItems>
      </cacheField>
      <cacheField name="Year">
       <sharedItems containsNumber="1" containsString="0" containsSemiMixedTypes="0"/>
      </cacheField>
      <cacheField name="Price">
       <sharedItems containsNumber="1" containsString="0" containsSemiMixedTypes="0"/>
      </cacheField>
      <cacheField name="Count">
       <sharedItems containsNumber="1" containsString="0" containsSemiMixedTypes="0"/>
      </cacheField>
  </cacheFields>
  </pivotCacheDefinition>
  |]
  
  stripContentSpaces :: Document -> Document
  stripContentSpaces doc@Document {documentRoot = root} =
    doc {documentRoot = go root}
    where
      go e@Element {elementNodes = nodes} =
        e {elementNodes = mapMaybe goNode nodes}
      goNode (NodeElement el) = Just $ NodeElement (go el)
      goNode t@(NodeContent txt) =
        if T.strip txt == T.empty
          then Nothing
          else Just t
      goNode other = Just $ other
  