import logging
import os

import test_cases.test_simulation_tumor_growth.testing_config as test_config

config.USE_ADJOINT = True
from glimslib.simulation.simulation_tumor_growth import TumorGrowth
from glimslib import fenics_local as fenics
import glimslib.utils.file_utils as fu

# ==============================================================================
# Logging settings
# ==============================================================================

logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO)
fenics.set_log_level(fenics.PROGRESS)

# ==============================================================================
# Problem Settings
# ==============================================================================


class Boundary(fenics.SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary


# Mesh
nx = ny = 50
mesh = fenics.RectangleMesh(fenics.Point(-5, -5), fenics.Point(5, 5), nx, ny)
import os

config.USE_ADJOINT = True
import test_cases.test_simulation_tumor_growth.testing_config as test_config

from glimslib.simulation import TumorGrowthBrain
from glimslib import fenics_local as fenics, config
import glimslib.utils.file_utils as fu
import glimslib.utils.data_io as dio

# ==============================================================================
# Logging settings
# ==============================================================================

logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO)
fenics.set_log_level(fenics.CRITICAL)

# ==============================================================================
# Load 2D Mesh from IMAGE
# ==============================================================================
path_to_hdf5_mesh = os.path.join(config.test_data_dir,
                                 'brain_atlas_mesh_2d_reduced_domain.h5')
mesh, subdomains, boundaries = dio.read_mesh_hdf5(path_to_hdf5_mesh)

# ==============================================================================
# Problem Settings
# ==============================================================================


class Boundary(fenics.SubDomain):
    def inside(self, x, on_boundary):
These need to be defined for each implementation of this base class.
"""

import logging
import os
from abc import ABC, abstractmethod

from glimslib import fenics_local as fenics
from glimslib.simulation_helpers.helper_classes import SubDomains, FunctionSpace, \
                                            BoundaryConditions, Parameters, Results, Plotting
from glimslib.simulation import config

# FENICS (and related) Logger settings
if fenics.is_version("<2018.1.x"):
    fenics.set_log_level(fenics.WARNING)
else:
    fenics.set_log_level(fenics.LogLevel.WARNING)
logger_names = ['FFC', 'UFL', 'dijitso', 'flufl']
for logger_name in logger_names:
    try:
        logger = logging.getLogger(logger_name)
        logger.setLevel(logging.WARNING)
    except:
        pass


class FenicsSimulation(ABC):
    """
    This class serves as 'master class' for the definition of time-dependent FEniCS problems that may differ in their
    underlying governing forms and input parameters.