#!/usr/bin/env python3

import asyncio
import json
import textwrap
from pathlib import Path
from unittest.mock import Mock

from mitmproxy import options
from mitmproxy.proxy.mode_servers import ServerInstance
from mitmproxy.tools.web import app
from mitmproxy.tools.web import master

here = Path(__file__).parent.absolute()

filename = here / "../src/js/__tests__/ducks/_tbackendstate.ts"


async def make() -> str:
    o = options.Options()
    m = master.WebMaster(o)

    si1 = ServerInstance.make("regular", m.proxyserver)
    sock1 = Mock()
    sock1.getsockname.return_value = ("127.0.0.1", 8080)
    sock2 = Mock()
    sock2.getsockname.return_value = ("::1", 8080)
    server = Mock()
    server.sockets = [sock1, sock2]
    si1._servers = [server]
    si2 = ServerInstance.make("reverse:example.com", m.proxyserver)
    si2.last_exception = RuntimeError("I failed somehow.")
    si3 = ServerInstance.make("socks5", m.proxyserver)
    si4 = ServerInstance.make("tun", m.proxyserver)
    si4._server = Mock()
    si4._server.tun_name = lambda: "tun0"
    m.proxyserver.servers._instances.update(
        {
            si1.mode: si1,
            si2.mode: si2,
            si3.mode: si3,
            si4.mode: si4,
        }
    )

    data = app.State.get_json(m)
    await m.done()

    data.update(available=True)
    data["contentViews"] = ["auto", "Raw"]
    data["version"] = "1.2.3"
    data["platform"] = "darwin"
    data["localModeUnavailable"] = None

    # language=TypeScript
    content = (
        "/** Auto-generated by web/gen/state_js.py */\n"
        "import type {BackendStateExtra} from '../../ducks/backendState';\n"
        "export function TBackendState(): Required<BackendStateExtra> {\n"
        "    return %s\n"
        "}\n"
        % textwrap.indent(json.dumps(data, indent=4, sort_keys=True), "    ").lstrip()
    )

    return content


if __name__ == "__main__":
    filename.write_bytes(asyncio.run(make()).encode())
