#! /usr/bin/env python

import os
import platform

from lab.environments import LocalEnvironment, BaselSlurmEnvironment
from downward.experiment import FastDownwardExperiment

# In the future, these modules should live in a separate
# "planning" or "solver" package.
from downward.reports.absolute import AbsoluteReport
from downward.reports.scatter import ScatterPlotReport

path_to_problem_files = 'problems/'

REMOTE = 'cluster' in platform.node() or 'login-infai' in platform.node()
BENCHMARKS_DIR = os.environ["DOWNWARD_BENCHMARKS"]
if REMOTE:
    ENV = BaselSlurmEnvironment(partition='infai_1', qos='normal', email='clemens.buechner@unibas.ch')
    SUITE = [os.path.abspath(path_to_problem_files + f) for f in os.listdir(path_to_problem_files) if os.path.isfile(os.path.join(path_to_problem_files, f))]
    REPO = '/infai/buecle01/thesis/cegar/cegar-rubiks-cube/'
else:
    ENV = LocalEnvironment(processes=2)
    SUITE = [path_to_problem_files + 'rubikscube_size=3_turns=1_problem=0.sas',
             path_to_problem_files + 'rubikscube_size=3_turns=2_problem=0.sas',
             path_to_problem_files + 'rubikscube_size=3_turns=5_problem=0.sas']
    REPO = '/home/clemi/Switchdrive/uni/lectures/semester6/Bachelorarbeit/cegar/cegar-rubiks-cube/'

ATTRIBUTES = ['coverage', 'expansions_until_last_jump', 'total_time', 'error', 'cost', 'initial_h_value']

# Create a new experiment.
exp = FastDownwardExperiment(environment=ENV)

pattern1 = '[ 0,  1,  2,  3]'  # first half of corner cubies
pattern2 = '[ 4,  5,  6,  7]'  # remaining corner cubies
pattern3 = '[ 8,  9, 10, 11]'  # first third of edge cubies
pattern4 = '[12, 13, 14, 15]'  # second third of edge cubies
pattern5 = '[16, 17, 18, 19]'  # remaining edge cubies
abstractions = (('[projections(manual_patterns([{pattern1}]), create_complete_transition_system=true),' +
                 ' projections(manual_patterns([{pattern2}]), create_complete_transition_system=true),' +
                 ' projections(manual_patterns([{pattern3}]), create_complete_transition_system=true),' +
                 ' projections(manual_patterns([{pattern4}]), create_complete_transition_system=true),' +
                 ' projections(manual_patterns([{pattern5}]), create_complete_transition_system=true)]').format(**locals()))
corner_abstraction = '[projections(manual_patterns([{pattern1}]), create_complete_transition_system=true)]'.format(**locals())
edge_abstraction = '[projections(manual_patterns([{pattern3}]), create_complete_transition_system=true)]'.format(**locals())
ALGORITHMS = [('blind', ['--search', 'astar(blind())']),
              ('max-manual-pdb', ['--search', 'astar(maximize({abstractions}))'.format(**locals())]),
              ('max-systematic-pdb', ['--search', 'astar(maximize([projections(systematic(3), ' +
                                      'create_complete_transition_system=true)]))']),
              ('single-corner-pattern', ['--search', 'astar(maximize({corner_abstraction}))'.format(**locals())]),
              ('single-edge-pattern', ['--search', 'astar(maximize({edge_abstraction}))'.format(**locals())]),
              ('cegar', ['--search', 'astar(cegar(subtasks=[original()], max_states=infinity, ' +
                         'max_transitions=infinity, max_time=900))']),
              ('merge-and-shrink', ['--search', 'astar(merge_and_shrink(' +
                                    'shrink_strategy=shrink_bisimulation(greedy=false),' +
                                    'merge_strategy=merge_sccs(order_of_sccs=topological,' +
                                    'merge_selector=score_based_filtering(scoring_functions=[goal_relevance,dfp,total_order])),' +
                                    'label_reduction=exact(before_shrinking=true,before_merging=false),' +
                                    'max_states=50000,threshold_before_merge=1))'])]

REV = 'c38a181'
REVNICK = 'latest'

for algo_name, algo_config in ALGORITHMS:
    exp.add_algorithm(REVNICK + ':' + algo_name, REPO, REV, algo_config, driver_options=['--search'])

for task in SUITE:
    exp.add_task(domain='rubiks-cube', problem=os.path.basename(task), problem_file=task)

# Make a report.
exp.add_report(
    AbsoluteReport(attributes=ATTRIBUTES),
    outfile='report.html')

# Compare the number of expansions in a scatter plot.
for algo1, config1 in ALGORITHMS:
    for algo2, config2 in ALGORITHMS:
        if algo1 != algo2:
            name1 = REVNICK + ':' + algo1
            name2 = REVNICK + ':' + algo2
            exp.add_report(
                ScatterPlotReport(
                    attributes=['expansions'], filter_algorithm=[name1, name2], format='tex'),
                outfile='{algo1}-vs-{algo2}.tex'.format(**locals()))

# Parse the commandline and run the specified steps.
exp.run_steps()
