import io
import json
import zipfile

from riff_pbix import (
    parse_report_layout,
    parse_data_model,
    parse_mashup,
    parse_connections,
)


def _build_pbix_zip(include_connections: bool = True):
    mem = io.BytesIO()
    with zipfile.ZipFile(mem, "w") as z:
        layout = {
            "sections": [
                {
                    "displayName": "Page 1",
                    "name": "section1",
                    "width": 1280,
                    "height": 720,
                    "visualContainers": [
                        {
                            "x": 0,
                            "y": 0,
                            "width": 300,
                            "height": 200,
                            "z": 1,
                            "tabOrder": 0,
                            "config": json.dumps(
                                {
                                    "name": "visual1",
                                    "singleVisual": {
                                        "visualType": "clusteredColumnChart",
                                        "prototypeQuery": {
                                            "From": [{"Entity": "Sales"}],
                                            "Select": [
                                                {"Column": {"Property": "Region"}, "Name": "Region"},
                                                {"Measure": {"Property": "Revenue"}, "Name": "Revenue"},
                                            ],
                                        },
                                        "vcObjects": {
                                            "title": [
                                                {
                                                    "properties": {
                                                        "text": {
                                                            "expr": {
                                                                "Literal": {"Value": "Revenue by Region"}
                                                            }
                                                        }
                                                    }
                                                }
                                            ]
                                        },
                                    },
                                }
                            ),
                        }
                    ],
                }
            ]
        }
        z.writestr("Report/Layout", json.dumps(layout).encode("utf-16-le"))

        model = {
            "model": {
                "tables": [
                    {
                        "name": "Sales",
                        "columns": [{"name": "Region", "dataType": "string"}],
                        "measures": [
                            {"name": "Revenue", "expression": "SUM('Sales'[Amount])"}
                        ],
                        "hierarchies": [],
                    }
                ],
                "relationships": [],
            }
        }
        z.writestr("DataModelSchema", json.dumps(model).encode("utf-16-le"))

        inner_mem = io.BytesIO()
        with zipfile.ZipFile(inner_mem, "w") as inner:
            inner.writestr("Formulas/Section1.m", "shared Sales = let Source = 1 in Source;")
        z.writestr("DataMashup", inner_mem.getvalue())

        if include_connections:
            z.writestr("Connections", json.dumps({"connections": []}).encode("utf-8"))

    mem.seek(0)
    return mem


def test_parse_report_layout():
    pbix = _build_pbix_zip()
    with zipfile.ZipFile(pbix) as z:
        layout = parse_report_layout(z)

    assert "pages" in layout
    assert len(layout["pages"]) == 1
    assert layout["pages"][0]["visuals"][0]["type"] == "clusteredColumnChart"
    assert layout["all_visuals_flat"]


def test_parse_data_model():
    pbix = _build_pbix_zip()
    with zipfile.ZipFile(pbix) as z:
        model = parse_data_model(z)

    assert model["tables"][0]["name"] == "Sales"
    assert model["tables"][0]["measures"][0]["name"] == "Revenue"


def test_parse_mashup():
    pbix = _build_pbix_zip()
    with zipfile.ZipFile(pbix) as z:
        mashup = parse_mashup(z)

    assert "queries" in mashup
    assert mashup["queries"][0]["name"] == "Sales"


def test_parse_connections():
    pbix = _build_pbix_zip(include_connections=True)
    with zipfile.ZipFile(pbix) as z:
        connections = parse_connections(z)

    assert connections == {"connections": []}
