import json
import os
import posixpath
import socket

from mysos.common import zookeeper
from mysos.common.testing import Fake
from mysos.executor.executor import MysosExecutor
from mysos.executor.mysos_task_runner import MysosTaskRunner, TaskRunnerProvider
from mysos.executor.noop_installer import NoopPackageInstaller
from mysos.executor.sandbox import Sandbox

from .fake import FakeTaskControlProvider

import mesos.native
from twitter.common import app, log
from twitter.common.log.options import LogOptions
from twitter.common.zookeeper.serverset.endpoint import Endpoint, ServiceInstance
from zake.fake_client import FakeClient


SANDBOX_ROOT = os.path.join(os.path.realpath('.'), "sandbox")


class FakeTaskRunnerProvider(TaskRunnerProvider):
  """
    Creates a MysosTaskRunner with FakeTaskControl for testing purposes.
    NOTE: zake is used so a running ZK server is not required.
  """

  def __init__(self, task_control_provider):
    self._task_control_provider = task_control_provider

  def from_task(self, task, sandbox):
    data = json.loads(task.data)
    cluster_name, port, zk_url = data['cluster'], data['port'], data['zk_url']

    _, servers, path = zookeeper.parse(zk_url)

    zk_client = FakeClient()
    zk_client.start()
    self_instance = ServiceInstance(Endpoint(socket.gethostbyname(socket.gethostname()), port))
    task_control = self._task_control_provider.from_task(task, sandbox)

    return MysosTaskRunner(
        self_instance,
        zk_client,
        posixpath.join(path, cluster_name),
        NoopPackageInstaller(),
        task_control,
        Fake())


# This is a testing executor. We log more verbosely.
LogOptions.disable_disk_logging()
LogOptions.set_stderr_log_level('google:DEBUG')


def proxy_main():
  def main(args, options):
    log.info('Starting testing mysos executor')

    executor = MysosExecutor(
        FakeTaskRunnerProvider(FakeTaskControlProvider()), Sandbox(SANDBOX_ROOT))

    driver = mesos.native.MesosExecutorDriver(executor)
    driver.run()

    log.info('Exiting executor main')

  app.main()
