import subprocess
import time

from heros import RemoteHERO

from qcodes.instrument import Instrument
import pytest
import json
from unittest import mock
import os


class ExampleBaseVoltageSource(Instrument):
    _voltage: float = 0.0

    def __init__(self, name: str):
        super().__init__(name)

        self.add_parameter(
            "voltage",
            unit="V",
            abstract=False,
            get_cmd=self._get_voltage,
            set_cmd=self._set_voltage,
        )
        self.add_parameter("current", unit="A", get_cmd=None, set_cmd=None)

    def _get_voltage(self):
        return self._voltage

    def _set_voltage(self, value):
        self._voltage = value


@pytest.fixture()
def qcodes_env():
    boss_config = json.dumps(
        {
            "_id": "test_dev_qcodes",
            "classname": "tests.test_ext_libs.ExampleBaseVoltageSource",
            "arguments": {
                "parameters": ["voltage", "current"],
            },
        }
    )
    with mock.patch.dict(os.environ, {"BOSS_QCODES": boss_config}):
        yield


def test_qcodes(qcodes_env, cleanup):
    _boss_process = subprocess.Popen(
        [
            "python",
            "-m",
            "boss.starter",
            "-e",
            "BOSS_QCODES",
            "--log=debug",
            "--realm=test",
        ],
        qcodes_env,
    )

    cleanup["boss"].append([_boss_process, None])
    time.sleep(2)

    hero = RemoteHERO("test_dev_qcodes", realm="test")
    cleanup["heros"].append(hero)

    assert hasattr(hero, "voltage")
    hero.voltage = 100
    assert hero.voltage == 100
