# -*- coding: utf-8 -*-

import logging
import os
import traceback
import unittest

import py2neo
import py2neo.database.status
from click.testing import CliRunner

from pybel import cli
from pybel.constants import PYBEL_CONTEXT_TAG, METADATA_NAME
from pybel.io import from_pickle, from_json, from_path
from pybel.manager.database_io import from_database
from tests.constants import test_bel_simple, BelReconstitutionMixin, mock_bel_resources, test_bel_thorough, \
    expected_test_thorough_metadata

log = logging.getLogger(__name__)


class TestCli(BelReconstitutionMixin, unittest.TestCase):
    def setUp(self):
        self.runner = CliRunner()

    @mock_bel_resources
    def test_convert(self, mock_get):

        with self.runner.isolated_filesystem():
            test_csv = os.path.abspath('test.csv')
            test_gpickle = os.path.abspath('test.gpickle')
            test_canon = os.path.abspath('test.bel')
            connection = 'sqlite:///' + os.path.abspath('test.db')

            args = [
                'convert',
                # Input
                '--path', test_bel_thorough,
                '--connection', connection,
                # Outputs
                '--csv', test_csv,
                '--pickle', test_gpickle,
                '--bel', test_canon,
                '--store-connection', connection,
                '--allow-nested'
            ]

            result = self.runner.invoke(cli.main, args)
            self.assertEqual(0, result.exit_code, msg=traceback.format_tb(result.exc_info[2]))

            self.assertTrue(os.path.exists(test_csv))

            self.bel_thorough_reconstituted(from_pickle(test_gpickle))
            self.bel_thorough_reconstituted(from_path(test_canon))
            self.bel_thorough_reconstituted(from_database(expected_test_thorough_metadata[METADATA_NAME],
                                                          connection=connection))

    @mock_bel_resources
    def test_convert_json(self, mock_get):
        with self.runner.isolated_filesystem():
            test_json = os.path.abspath('test.json')
            connection = 'sqlite:///' + os.path.abspath('test.db')

            args = [
                'convert',
                '--path', test_bel_thorough,
                '--json', test_json,
                '--connection', connection,
                '--allow-nested'
            ]

            result = self.runner.invoke(cli.main, args)
            self.assertEqual(0, result.exit_code, msg=result.exc_info)

            self.bel_thorough_reconstituted(from_json(test_json))

    @unittest.skipUnless('NEO_PATH' in os.environ, 'Need environmental variable $NEO_PATH')
    @mock_bel_resources
    def test_neo4j_remote(self, mock_get):
        test_context = 'PYBEL_TEST_CTX'
        neo_path = os.environ['NEO_PATH']

        try:
            neo = py2neo.Graph(neo_path)
            neo.data('match (n)-[r]->() where r.{}="{}" detach delete n'.format(PYBEL_CONTEXT_TAG, test_context))
        except py2neo.database.status.GraphError:
            self.skipTest("Can't query Neo4J ")
        except:
            self.skipTest("Can't connect to Neo4J server")
        else:
            with self.runner.isolated_filesystem():
                connection = 'sqlite:///' + os.path.abspath('test.db')
                args = [
                    'convert',
                    '--path', test_bel_simple,
                    '--connection', connection,
                    '--neo', neo_path,
                    '--neo-context', test_context
                ]
                self.runner.invoke(cli.main, args)

                q = 'match (n)-[r]->() where r.{}="{}" return count(n) as count'.format(PYBEL_CONTEXT_TAG, test_context)
                count = neo.data(q)[0]['count']
                self.assertEqual(14, count)

@@ -493,16 +493,64 @@
 metadata
+%0Afrom tests.constants import TemporaryCacheMixin
 %0A%0Alog = 
@@ -593,16 +593,37 @@
 TestCli(
+TemporaryCacheMixin, 
 BelRecon
@@ -640,27 +640,8 @@
 ixin
-, unittest.TestCase
 ):%0A 
@@ -660,16 +660,53 @@
 (self):%0A
+        super(TestCli, self).setUp()%0A
         
@@ -1009,75 +1009,8 @@
 el')
-%0A            connection = 'sqlite:///' + os.path.abspath('test.db')
 %0A%0A  
@@ -1148,32 +1148,37 @@
 '--connection', 
+self.
 connection,%0A    
@@ -1343,32 +1343,37 @@
 re-connection', 
+self.
 connection,%0A    
@@ -1936,16 +1936,21 @@
 nection=
+self.
 connecti
@@ -2126,75 +2126,8 @@
 on')
-%0A            connection = 'sqlite:///' + os.path.abspath('test.db')
 %0A%0A  
@@ -2278,32 +2278,37 @@
 '--connection', 
+self.
 connection,%0A    
@@ -3199,79 +3199,8 @@
 ():%0A
-                connection = 'sqlite:///' + os.path.abspath('test.db')%0A
     
@@ -3334,16 +3334,21 @@
 ction', 
+self.
 connecti

Update filesystem and connection management in CLI test