#! /usr/bin/env python

import os
import sys
import pathlib
import inspect

import waves

# Comments used in tutorial code snippets: marker-1

# Accept command line options with fall back default values
AddOption(
    "--build-dir",
    dest="variant_dir_base",
    default="build",
    nargs=1,
    type="string",
    action="store",
    metavar="DIR",
    help="SCons build (variant) root directory. Relative or absolute path. (default: '%default')"
)
AddOption(
    "--unconditional-build",
    dest="unconditional_build",
    default=False,
    action="store_true",
    help="Boolean flag to force building of conditionally ignored targets, e.g. if the target's action program is missing" \
            " and it would normally be ignored. (default: '%default')"
)

# Comments used in tutorial code snippets: marker-2

# Inherit user's full environment and set project variables
env = Environment(ENV=os.environ.copy(),
                  variant_dir_base=GetOption("variant_dir_base"),
                  unconditional_build=GetOption("unconditional_build"),
                  TARFLAGS="-c -j",
                  TARSUFFIX=".tar.bz2")

# Comments used in tutorial code snippets: marker-3

# Find required programs for conditional target ignoring and absolute path for use in target actions
env['abaqus'] = waves.scons_extensions.add_program(["/apps/abaqus/Commands/abq2023", "abq2023"], env)

# Comments used in tutorial code snippets: marker-4

# Set project internal variables and variable substitution dictionaries
project_name = 'WAVES-TUTORIAL'
version = '0.1.0'
archive_prefix = f"{project_name}-{version}"
project_configuration = pathlib.Path(inspect.getfile(lambda: None))
project_dir = project_configuration.parent
abaqus_source_dir = "eabm_package/abaqus"
python_source_dir = "eabm_package/python"
project_variables = {
    "project_configuration": str(project_configuration),
    'project_name': project_name,
    'project_dir': str(project_dir),
    'version': version,
    'abaqus_source_abspath': str(project_dir / abaqus_source_dir),
    'python_source_abspath': str(project_dir / python_source_dir),
    'datacheck_alias': 'datacheck',
    'archive_prefix': archive_prefix
}
for key, value in project_variables.items():
    env[key] = value

# Make the EABM package importable for: (1) SConscript files and (2) Python and Abaqus Python environments
sys.path.insert(0, str(project_dir))
env.PrependENVPath("PYTHONPATH", str(project_dir))

# Comments used in tutorial code snippets: marker-5

# Build path object for extension and re-use
variant_dir_base = pathlib.Path(env['variant_dir_base'])

# Add custom builders
env.Append(BUILDERS={
    'AbaqusJournal': waves.scons_extensions.abaqus_journal(program=env['abaqus']),
    'AbaqusSolver': waves.scons_extensions.abaqus_solver(program=env['abaqus']),
    'AbaqusExtract': waves.scons_extensions.abaqus_extract(program=env['abaqus']),
    'PythonScript': waves.scons_extensions.python_script()})

# Comments used in tutorial code snippets: marker-6

# Create a datacheck alias for reduced cost regression testing
env.Alias(env['datacheck_alias'])

# Add simulation targets
workflow_configurations = [
    'tutorial_01_geometry',
    'tutorial_02_partition_mesh',
    'tutorial_03_solverprep',
    'tutorial_04_simulation',
    'tutorial_05_parameter_substitution',
    'tutorial_06_include_files',
    'tutorial_07_cartesian_product',
    'tutorial_08_data_extraction',
    'tutorial_09_post_processing',
    'tutorial_10_regression_testing',
    'tutorial_11_archival',
    'tutorial_task_reuse'
]
for workflow in workflow_configurations:
    build_dir = variant_dir_base / workflow
    SConscript(workflow, variant_dir=build_dir, exports='env', duplicate=False)

# Comments used in tutorial code snippets: marker-7

# Add default target list to help message
env.Default()  # Empty defaults list to avoid building all simulation targets by default
# Add aliases to help message so users know what build target options are available
# This must come *after* all expected Alias definitions and SConscript files.
waves.scons_extensions.project_help_message()

# Comments used in tutorial code snippets: marker-8
