import os
import uuid

import numpy as np
from bw2data import Database, Method, projects

basedir = os.path.dirname(os.path.abspath(__file__))

# Technosphere matrix

[[1, 2, -3], [0, 0.5, -2], [-0.1, 0, 1]]

# Biosphere matrix

[[0, 1, 2], [7, 5, 0]]

# Characterization matrix

[[4, 0], [0, -2]]

# A^{-1}

[
    [2 / 3, 4 / 15, 2 / 30],
    [-(2 + 2 / 3), 14 / 15, -4 / 15],
    [-(3 + 1 / 3), 2 + 2 / 3, 2 / 3],
]


def write_database():
    bio_data = {
        ("bio", "a"): {"exchange": [], "type": "biosphere"},
        ("bio", "b"): {"exchange": [], "type": "biosphere"},
    }
    Database("bio").write(bio_data)

    tech_data = {
        ("test", "1"): {
            "exchanges": [
                {
                    "amount": 1,
                    "type": "production",
                    "input": ("test", "1"),
                    "uncertainty type": 0,
                },
                {
                    "amount": 0.1,
                    "type": "technosphere",
                    "input": ("test", "3"),
                    "uncertainty type": 0,
                },
                {
                    "amount": 7,
                    "type": "biosphere",
                    "input": ("bio", "b"),
                    "uncertainty type": 0,
                },
            ],
        },
        ("test", "2"): {
            "exchanges": [
                {
                    "amount": 0.5,
                    "type": "production",
                    "input": ("test", "2"),
                    "uncertainty type": 0,
                },
                {
                    "amount": -2,
                    "type": "technosphere",
                    "input": ("test", "1"),
                    "uncertainty type": 0,
                },
                {
                    "amount": 1,
                    "type": "biosphere",
                    "input": ("bio", "a"),
                    "uncertainty type": 0,
                },
                {
                    "amount": 5,
                    "type": "biosphere",
                    "input": ("bio", "b"),
                    "uncertainty type": 0,
                },
            ],
        },
        ("test", "3"): {
            "exchanges": [
                {
                    "amount": 1,
                    "type": "production",
                    "input": ("test", "3"),
                    "uncertainty type": 0,
                },
                {
                    "amount": 3,
                    "type": "technosphere",
                    "input": ("test", "1"),
                    "uncertainty type": 0,
                },
                {
                    "amount": 2,
                    "type": "technosphere",
                    "input": ("test", "2"),
                    "uncertainty type": 0,
                },
                {
                    "amount": 2,
                    "type": "biosphere",
                    "input": ("bio", "a"),
                    "uncertainty type": 0,
                },
            ],
        },
    }

    Database("test").write(tech_data)

    cfs = [
        (("bio", "a"), 4),
        (("bio", "b"), -2),
    ]

    Method(("m",)).register()
    Method(("m",)).write(cfs)


def build_single_presample_array():
    from presamples import create_presamples_package

    tech_indices = [
        (("test", "1"), ("test", "2"), "technosphere"),
        (("test", "2"), ("test", "2"), "production"),
    ]

    tech_samples = np.array(
        (
            [1],
            [1],
        )
    )

    bio_indices = [
        (("bio", "a"), ("test", "2")),
        (("bio", "b"), ("test", "2")),
        (("bio", "b"), ("test", "1")),
    ]

    bio_samples = np.array(
        (
            [10],
            [1],
            [0],
        )
    )

    cf_indices = [("bio", "a")]

    cf_samples = np.array(([1],))

    create_presamples_package(
        matrix_data=[
            (tech_samples, tech_indices, "technosphere"),
            (bio_samples, bio_indices, "biosphere"),
            (cf_samples, cf_indices, "cf"),
        ],
        id_="single-sample",
        name="single-sample",
        dirpath=basedir,
        overwrite=True,
        seed=54321,
    )


def build_multi_presample_array_unseeded():
    from presamples import create_presamples_package

    tech_indices = [
        (("test", "1"), ("test", "2"), "technosphere"),
        (("test", "2"), ("test", "2"), "production"),
    ]

    tech_samples = np.array(
        (
            [1, 2, 3],
            [100, 101, 102],
        )
    )

    bio_indices = [
        (("bio", "a"), ("test", "2")),
        (("bio", "b"), ("test", "2")),
        (("bio", "b"), ("test", "1")),
    ]

    bio_samples = np.array(
        (
            [10, 11, 12],
            [1, 2, 3],
            [0, -1, -2],
        )
    )

    create_presamples_package(
        matrix_data=[
            (tech_samples, tech_indices, "technosphere"),
            (bio_samples, bio_indices, "biosphere"),
        ],
        id_="unseeded",
        name="unseeded",
        dirpath=basedir,
        overwrite=True,
    )


def build_multi_presample_array():
    from presamples import create_presamples_package

    tech_indices = [
        (("test", "1"), ("test", "2"), "technosphere"),
        (("test", "2"), ("test", "2"), "production"),
    ]

    tech_samples = np.array(
        (
            [1, 2, 3],
            [100, 101, 102],
        )
    )

    bio_indices = [
        (("bio", "a"), ("test", "2")),
        (("bio", "b"), ("test", "2")),
        (("bio", "b"), ("test", "1")),
    ]

    bio_samples = np.array(
        (
            [10, 11, 12],
            [1, 2, 3],
            [0, -1, -2],
        )
    )

    create_presamples_package(
        matrix_data=[
            (tech_samples, tech_indices, "technosphere"),
            (bio_samples, bio_indices, "biosphere"),
        ],
        id_="multi",
        name="multi",
        dirpath=basedir,
        overwrite=True,
        seed=42,
    )


def build_multi_presample_sequential_array():
    from presamples import create_presamples_package

    tech_indices = [
        (("test", "1"), ("test", "2"), "technosphere"),
        (("test", "2"), ("test", "2"), "production"),
    ]

    tech_samples = np.array(
        (
            [1, 2, 3],
            [100, 101, 102],
        )
    )

    bio_indices = [
        (("bio", "a"), ("test", "2")),
        (("bio", "b"), ("test", "2")),
        (("bio", "b"), ("test", "1")),
    ]

    bio_samples = np.array(
        (
            [10, 11, 12],
            [1, 2, 3],
            [0, -1, -2],
        )
    )

    create_presamples_package(
        matrix_data=[
            (tech_samples, tech_indices, "technosphere"),
            (bio_samples, bio_indices, "biosphere"),
        ],
        id_="seq",
        name="seq",
        dirpath=basedir,
        overwrite=True,
        seed="sequential",
    )


if __name__ == "__main__":
    name = "test-builder-{}".format(uuid.uuid4().hex)
    if name in projects:
        raise ValueError("Test project name not unique; please run again.")
    try:
        projects.set_current(name)
        write_database()
        build_single_presample_array()
        build_multi_presample_array()
        build_multi_presample_array_unseeded()
        build_multi_presample_sequential_array()
    finally:
        projects.delete_project(delete_dir=True)
