# -*- coding: utf-8 -*-
"""Regression tests for the BTCQ versioning scheme and the .electrum-btcq
data directory.

The versioning scheme is documented in electrum/version.py:
ELECTRUM_VERSION (upstream baseline, frozen) + BTCQ_PATCH_VERSION (BTCQ
patch counter, bumped per BTCQ release) → __version__ (display form,
e.g. "4.7.2-btcq.3") + PEP440_VERSION (pip-compatible, e.g. "4.7.2+btcq.3").

The data directory is intentionally separate from upstream Bitcoin
Electrum so the two clients can coexist without trampling each other's
wallets/configs/certs.
"""
import os
import unittest
from unittest.mock import patch

from electrum import version
from electrum.util import user_dir


class BtcqVersioningScheme(unittest.TestCase):
    def test_electrum_version_is_upstream_baseline(self):
        # Frozen at the upstream Electrum version we forked from. Bumps
        # only on rebase, which is a deliberate separate event from any
        # BTCQ-side release.
        self.assertEqual(version.ELECTRUM_VERSION, '4.7.2')

    def test_btcq_patch_version_is_int_at_least_1(self):
        # An integer counter, never 0 (since the original fork is
        # implicitly btcq.1; we never publish a btcq.0).
        self.assertIsInstance(version.BTCQ_PATCH_VERSION, int)
        self.assertGreaterEqual(version.BTCQ_PATCH_VERSION, 1)

    def test_display_version_format(self):
        # Display form: "<base>-btcq.<n>". Used everywhere user-visible
        # (wallet --version, server User-Agent, AppImage filename via
        # git describe, RPM %changelog).
        expected = f"{version.ELECTRUM_VERSION}-btcq.{version.BTCQ_PATCH_VERSION}"
        self.assertEqual(version.__version__, expected)
        self.assertIn('-btcq.', version.__version__)

    def test_pep440_version_format(self):
        # PEP 440 local-version form: "<base>+btcq.<n>". Used by setup.py
        # (PEP 440 disallows '-' in versions; '+' is the local-version
        # separator). Surfaces in sdist filenames.
        expected = f"{version.ELECTRUM_VERSION}+btcq.{version.BTCQ_PATCH_VERSION}"
        self.assertEqual(version.PEP440_VERSION, expected)
        self.assertIn('+btcq.', version.PEP440_VERSION)

    def test_setup_py_uses_pep440_form(self):
        # Smoke check: setup.py reads version.PEP440_VERSION (not
        # ELECTRUM_VERSION) so wheels/sdists get a fork-disambiguated
        # filename rather than colliding with upstream Electrum's.
        setup_py = os.path.join(
            os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
            'setup.py',
        )
        with open(setup_py, 'r') as f:
            contents = f.read()
        self.assertIn('version.PEP440_VERSION', contents)
        self.assertNotIn('version=version.ELECTRUM_VERSION', contents)


class BtcqUserDir(unittest.TestCase):
    """Verify wallet data lands in ~/.electrum-btcq, not ~/.electrum."""

    def test_posix_default_uses_electrum_btcq(self):
        with patch.dict(os.environ, {'HOME': '/home/testuser'}, clear=False):
            os.environ.pop('BTCQ_ELECTRUMDIR', None)
            os.environ.pop('ANDROID_DATA', None)
            self.assertEqual(user_dir(), '/home/testuser/.electrum-btcq')

    def test_btcq_electrumdir_env_override_takes_priority(self):
        with patch.dict(os.environ, {'BTCQ_ELECTRUMDIR': '/custom/path', 'HOME': '/home/testuser'}, clear=False):
            self.assertEqual(user_dir(), '/custom/path')

    def test_legacy_electrumdir_env_is_ignored(self):
        # ELECTRUMDIR is the upstream Electrum env var. Honoring it would
        # re-introduce the coexistence collision the data-dir change is
        # designed to fix. Set it to a Bitcoin-Electrum-style value and
        # confirm we ignore it in favor of the BTCQ default.
        env = {'ELECTRUMDIR': '/bitcoin/electrum/dir', 'HOME': '/home/testuser'}
        with patch.dict(os.environ, env, clear=False):
            os.environ.pop('BTCQ_ELECTRUMDIR', None)
            os.environ.pop('ANDROID_DATA', None)
            self.assertEqual(user_dir(), '/home/testuser/.electrum-btcq')


class CommandsVersionInfo(unittest.IsolatedAsyncioTestCase):
    """Regression: from-source runs of `electrum-btcq version_info` errored
    with `'_EccFast' object has no attribute 'version_info'` because the
    BTCQ-vendored electrum_ecc shim only exported is_using_fast_ecc and
    upstream's commands.py:807 calls ecc_fast.version_info() blindly.
    Bundled-AppImage runs were unaffected (full upstream electrum_ecc in
    the venv). Stub method on _EccFast keeps the call working from source.
    """

    async def test_version_info_returns_dict(self):
        from electrum.commands import Commands
        info = await Commands(config=None, network=None, daemon=None).version_info()
        self.assertIsInstance(info, dict)
        # the BTCQ display version surfaces here under the new
        # versioning scheme (was ELECTRUM_VERSION = upstream baseline only)
        self.assertEqual(info['electrum.version'], version.__version__)


if __name__ == '__main__':
    unittest.main()
