package DMLSSTRequirements {
    private import Requirements::*;
    public import ScalarValues::*;

    requirement def EupsTagInBuildEmail {
        doc /* Provide the eups-tag assigned to a build within the email response. */
        attribute id : String = "DM-947";
        attribute eups_tag_provided : Boolean;
        attribute email_sent : Boolean;
        require constraint TagProvidedInEmail {
            email_sent == true implies eups_tag_provided == true
        }
    }

    requirement def UpgradeExternalPackages {
        doc /* Uprev LSST packages to match HSC tested versions. */
        attribute id : String = "DM-720";
        attribute lsst_version_matches_hsc : Boolean;
    }

    requirement def SaveManifestForFailedBuild {
        doc /* Save manifest file of failed build to well-known location for developer debug. */
        attribute id : String = "DM-702";
        attribute build_failed : Boolean;
        attribute manifest_saved : Boolean;
        attribute location_provided_in_notification : Boolean;
        require constraint SaveManifestOnFailure {
            build_failed == true implies manifest_saved == true
        }
        require constraint NotifyLocationOnFailure {
            build_failed == true implies location_provided_in_notification == true
        }
    }

    requirement def RelinkAstrometryDatasets {
        doc /* Relink astrometry_net_data datasets into new 8.0.0.0 stack. */
        attribute id : String = "DM-249";
        attribute datasets_linked : Boolean;
    }

    requirement def ReuseBuildIDs {
        doc /* Reuse buildIDs if nothing changed by comparing manifest against versiondb. */
        attribute id : String = "DM-95";
        attribute manifest_matches_versiondb : Boolean;
        attribute build_id_reused : Boolean;
        require constraint ReuseBuildIDOnMatch {
            manifest_matches_versiondb == true implies build_id_reused == true
        }
    }

    requirement def ModifyVersionNumberFormat {
        doc /* Use branchname-gSHA1ABBREV format for versions without tags, append +N for different dependencies. */
        attribute id : String = "DM-75";
        attribute tag_exists : Boolean;
        attribute version_format_valid : Boolean;
        require constraint VersionFormatValid {
            version_format_valid == true
        }
    }

    requirement def CompleteSplitDRPReport {
        doc /* Pull all portions of Split DRP report into single coherent document. */
        attribute id : String = "DM-74";
        attribute report_complete : Boolean;
    }

    requirement def ModifyGitolitePermissions {
        doc /* Allow issue/DM-NNNN branches in gitolite to differentiate from tickets/NNNN. */
        attribute id : String = "DM-28";
        attribute issue_branches_allowed : Boolean;
    }

    requirement def UpdateInstallationInstructions {
        doc /* Update Confluence instructions for Winter'14 stack installation. */
        attribute id : String = "DM-26";
        attribute instructions_updated : Boolean;
    }

    requirement def BuildWinter14Release {
        doc /* Run lsst-build scripts and eups distrib create to build Winter'14 release. */
        attribute id : String = "DM-25";
        attribute release_built : Boolean;
    }

    requirement def ConfirmStackBuildsOSX {
        doc /* Confirm stack builds on OS X 10.8. */
        attribute id : String = "DM-23";
        attribute builds_on_osx : Boolean;
    }

    requirement def UpdateNewinstallScript {
        doc /* Update newinstall.sh to check for git and python on user machines. */
        attribute id : String = "DM-22";
        attribute git_check_added : Boolean;
        attribute python_check_added : Boolean;
    }

    requirement def DetermineFinalURL {
        doc /* Determine final URL/location for W'14 stack files. */
        attribute id : String = "DM-21";
        attribute url_determined : Boolean;
    }

    requirement def ReleaseEUPS130 {
        doc /* Release EUPS 1.3.0 in RHL's github repository. */
        attribute id : String = "DM-20";
        attribute eups_released : Boolean;
    }

    requirement def FixCppParserIssues {
        doc /* Fix 12 issues in testCppParser related to CSS switch. */
        attribute id : String = "DM-600";
        attribute issues_fixed : Integer;
        attribute max_issues : Integer = 12;
        require constraint AllIssuesFixed {
            issues_fixed == max_issues
        }
    }

    requirement def UnitTestsInstallDirectory {
        doc /* Define and implement unit tests install directory structure. */
        attribute id : String = "DM-481";
        attribute install_directory_defined : Boolean;
    }

    requirement def FixTestQueryAnalysis {
        doc /* Fix 5 failing tests in testCppParser. */
        attribute id : String = "DM-372";
        attribute failing_tests : Integer;
        attribute max_failing : Integer = 5;
        require constraint NoFailingTests {
            failing_tests == 0
        }
    }

    requirement def ImproveCSSExceptionHandling {
        doc /* Introduce base class for CSS exceptions to enable individual exception catching. */
        attribute id : String = "DM-369";
        attribute base_exception_class_exists : Boolean;
    }

    requirement def CutQservRelease {
        doc /* Create fully functioning Qserv release with latest changes for Hackathon. */
        attribute id : String = "DM-334";
        attribute release_cut : Boolean;
    }

    requirement def JiraForQserv {
        doc /* Setup Jira for Qserv including task management and scrum board. */
        attribute id : String = "DM-309";
        attribute jira_configured : Boolean;
    }

    requirement def RenameSqlConfigToMySqlConfig {
        doc /* Rename SqlConfig class to MySqlConfig for consistency. */
        attribute id : String = "DM-304";
        attribute class_renamed : Boolean;
    }

    requirement def FixNamespacesInQservModules {
        doc /* Use namespace scopes in .cc files across all Qserv core modules. */
        attribute id : String = "DM-296";
        attribute namespaces_fixed : Boolean;
    }

    requirement def InvestigateXrdSsiInterface {
        doc /* Investigate new XrdSsi interface. */
        attribute id : String = "DM-291";
        attribute investigation_complete : Boolean;
    }

    requirement def ImproveAsyncQueryManagerErrorHandling {
        doc /* Throw and handle exceptions gracefully when AsyncQueryManager configuration is invalid. */
        attribute id : String = "DM-278";
        attribute invalid_config_detected : Boolean;
        attribute exception_thrown : Boolean;
        require constraint ThrowOnInvalidConfig {
            invalid_config_detected == true implies exception_thrown == true
        }
    }

    requirement def SetupDevTestEnvironment {
        doc /* Setup Qserv environment including dataset installation and validation. */
        attribute id : String = "DM-228";
        attribute environment_setup : Boolean;
        attribute dataset_installed : Boolean;
        attribute validation_complete : Boolean;
    }

    requirement def ReferenceTestServerXRootD {
        doc /* Setup reference test server using new XRootD. */
        attribute id : String = "DM-222";
        attribute server_configured : Boolean;
    }

    requirement def ImplementAsyncXrootDClient {
        doc /* Implement new async XrootD client. */
        attribute id : String = "DM-221";
        attribute client_implemented : Boolean;
    }

    requirement def ReworkJOINSupport {
        doc /* Add support for Ref*Match tables in JOIN operations. */
        attribute id : String = "DM-198";
        attribute join_support_added : Boolean;
    }

    requirement def DocumentAstrometryNetDataCreation {
        doc /* Document creation of astrometry_net_data index files and repositories with sky coverage limits. */
        attribute id : String = "DM-474";
        attribute documentation_complete : Boolean;
        attribute sky_coverage_limit_supported : Boolean;
    }

    requirement def PrioritizeBacklogSummer2014 {
        doc /* Define and rank-order backlog for Summer 2014 with team agreement. */
        attribute id : String = "DM-473";
        attribute epics_defined : Boolean;
        attribute stories_defined : Boolean;
        attribute backlog_prioritized : Boolean;
        attribute team_agreement_achieved : Boolean;
    }

    requirement def CreateLSSTsimProcessingExample {
        doc /* Create worked example of processing raw data with obs_lsstSim in Software User Guide. */
        attribute id : String = "DM-471";
        attribute example_created : Boolean;
        attribute includes_isr : Boolean;
        attribute includes_measurement : Boolean;
        attribute includes_catalog_creation : Boolean;
        attribute includes_visualization : Boolean;
    }

    requirement def LsstBuildUpdates {
        doc /* Update lsst-build interface based on first month feedback. */
        attribute id : String = "DM-466";
        attribute interface_updated : Boolean;
    }

    requirement def WriteJobAdsTucsonDM {
        doc /* Write job advertisements for Tucson DM positions. */
        attribute id : String = "DM-444";
        attribute job_ads_written : Boolean;
    }

    requirement def AcquireHipChatLicenses {
        doc /* Approve and acquire HipChat licenses for team. */
        attribute id : String = "DM-443";
        attribute licenses_acquired : Boolean;
        attribute min_users : Integer = 26;
    }

    requirement def SimplifyCoAddExample {
        doc /* Simplify co-addition example in Software User Guide to work on single-user machines. */
        attribute id : String = "DM-359";
        attribute example_simplified : Boolean;
        attribute works_on_single_user_machine : Boolean;
    }

    requirement def CreateDMTeamBoard {
        doc /* Create board with pictures and names of everyone in DM including alumni. */
        attribute id : String = "DM-319";
        attribute board_created : Boolean;
        attribute includes_alumni : Boolean;
    }

    requirement def DevelopConfluenceStructure {
        doc /* Define organizational structure for DM Confluence space. */
        attribute id : String = "DM-273";
        attribute structure_defined : Boolean;
    }

    requirement def SetupBuildbotCI {
        doc /* Setup Buildbot 0.8.8 CI system with slaves on common OS platforms. */
        attribute id : String = "DM-271";
        attribute buildbot_configured : Boolean;
        attribute slaves_setup : Boolean;
        attribute git_change_triggers_build : Boolean;
        attribute failure_email_sent : Boolean;
    }

    requirement def SaveGitBranchOnForcedPush {
        doc /* Create gitolite hook to save branch when forced push is detected. */
        attribute id : String = "DM-78";
        attribute hook_created : Boolean;
        attribute branch_saved_on_force_push : Boolean;
    }

    requirement def OpenLSSTMailingLists {
        doc /* Open LSST software mailing lists to public for community involvement. */
        attribute id : String = "DM-9";
        attribute mailing_lists_public : Boolean;
    }

    requirement def FinalizeDMMissionStatement {
        doc /* Finalize DM mission statement for LSST Software Stack development. */
        attribute id : String = "DM-8";
        attribute mission_statement_finalized : Boolean;
    }

    requirement def PixelFlagsAndClassification {
        doc /* Implement PixelsFlags, SkyCoordAlgorithm, and Classification with exception handling. */
        attribute id : String = "DM-463";
        attribute pixel_keys_implemented : Boolean;
        attribute exception_handling_added : Boolean;
    }

    requirement def TestFluxAlgorithms {
        doc /* Test NaiveFlux, GaussianFlux, and PsfFlux for compatibility with meas_algorithms. */
        attribute id : String = "DM-449";
        attribute algorithms_tested : Boolean;
        attribute compatible_with_meas_algorithms : Boolean;
    }

    requirement def SetupFluxAlgorithmsForTesting {
        doc /* Setup GaussianFlux and NaiveFlux with unit tests for processCcd testing. */
        attribute id : String = "DM-447";
        attribute algorithms_configured : Boolean;
        attribute unit_tests_added : Boolean;
    }

    requirement def TestFourAlgorithmsCompatibility {
        doc /* Test PsfFlux, SdssShape, SdssCentroid, SincFlux compatibility with meas_algorithms. */
        attribute id : String = "DM-445";
        attribute algorithms_tested : Boolean;
        attribute results_match : Boolean;
    }

    requirement def SetupFourAlgorithmsForProcessCcd {
        doc /* Make PsfFlux, SdssShape, SdssCentroid, SincFlux operational with processCcd. */
        attribute id : String = "DM-441";
        attribute algorithms_operational : Boolean;
        attribute unit_tests_added : Boolean;
    }

    requirement def AddSlotSupportMeasBase {
        doc /* Add slot support for meas_base-style flattened outputs in SourceTable. */
        attribute id : String = "DM-433";
        attribute slot_mechanism_updated : Boolean;
        attribute handles_flattened_representation : Boolean;
    }

    requirement def AddBasicFunctorKeys {
        doc /* Add basic FunctorKeys mechanism with implementations to support Slots. */
        attribute id : String = "DM-421";
        attribute functor_keys_added : Boolean;
    }

    requirement def AddVersioningToSourceTable {
        doc /* Add version to SourceTable, persist to FITS, enable backwards compatibility. */
        attribute id : String = "DM-384";
        attribute version_added : Boolean;
        attribute persisted_to_fits : Boolean;
        attribute backwards_compatible : Boolean;
    }

    requirement def SwitchFieldSeparatorToUnderscore {
        doc /* Switch from dot to underscore in afw::table fields with version-based backwards compatibility. */
        attribute id : String = "DM-242";
        attribute separator_switched : Boolean;
        attribute backwards_compatible : Boolean;
    }

    requirement def RefactorForcedTasks {
        doc /* Separate CmdLineTask from Measurement task in forced photometry. */
        attribute id : String = "DM-241";
        attribute tasks_refactored : Boolean;
        attribute shares_base_class : Boolean;
    }

    requirement def AddDerivativesOptimizer {
        doc /* Add derivatives-based optimizer to meas_multifit. */
        attribute id : String = "DM-17";
        attribute optimizer_added : Boolean;
    }

    requirement def BaseDMCSReplicatorInteraction {
        doc /* Demonstrate Base DMCS and Replicator interaction for simulator v1. */
        attribute id : String = "DM-554";
        attribute start_integration_sent : Boolean;
        attribute start_readout_sent : Boolean;
        attribute replicator_jobs_submitted : Boolean;
        attribute replicator_jobs_receive_readout : Boolean;
    }

    requirement def QservReleaseFinalBuild {
        doc /* Complete final build, testing and release cutting for Qserv 12.04. */
        attribute id : String = "DM-744";
        attribute build_complete : Boolean;
        attribute testing_complete : Boolean;
        attribute release_cut : Boolean;
    }

    requirement def UseGeomEupsPackage {
        doc /* Use geom eups package instead of downloading geometry.py during configuration. */
        attribute id : String = "DM-742";
        attribute geom_package_used : Boolean;
    }

    requirement def ReduceClientConfigFile {
        doc /* Use templates in client config file and retrieve values from mother config. */
        attribute id : String = "DM-710";
        attribute templates_used : Boolean;
        attribute retrieves_from_mother_config : Boolean;
    }

    requirement def CleanupCSSExceptionCode {
        doc /* Make CSS exception naming consistent with LSST conventions and documentation. */
        attribute id : String = "DM-707";
        attribute naming_consistent : Boolean;
        attribute matches_documentation : Boolean;
    }

    requirement def CleanupExtraFileNamesInDocstring {
        doc /* Remove explicit file names from doxygen comment blocks. */
        attribute id : String = "DM-706";
        attribute explicit_filenames_removed : Boolean;
    }

    requirement def MergeCSSKeys {
        doc /* Design and implement more compact CSS key structure. */
        attribute id : String = "DM-705";
        attribute design_complete : Boolean;
        attribute implementation_complete : Boolean;
    }

    requirement def RenameQservdataRepo {
        doc /* Rename git repository qservdata to qserv_testdata for consistency. */
        attribute id : String = "DM-699";
        attribute repository_renamed : Boolean;
    }

    requirement def EnhanceInstallProcedure {
        doc /* Add swigged target to build alias and manage configuration defaults. */
        attribute id : String = "DM-690";
        attribute swigged_target_added : Boolean;
    }

    requirement def DefineCppAPIForGeometry {
        doc /* Define C++ API for C++ Geometry. */
        attribute id : String = "DM-631";
        attribute api_defined : Boolean;
    }

    requirement def FixNonPartitionedTableDuplicates {
        doc /* Fix non-partitioned table queries returning duplicated rows. */
        attribute id : String = "DM-630";
        attribute duplicates_fixed : Boolean;
        attribute chunk_level_checked : Boolean;
    }

    requirement def FixORDERBYAndDISTINCT {
        doc /* Fix ORDER BY and DISTINCT reliability issues in qserv. */
        attribute id : String = "DM-626";
        attribute order_by_fixed : Boolean;
        attribute distinct_fixed : Boolean;
    }

    requirement def FixTooManyZookeeperConnections {
        doc /* Fix excessive connections from czar to zookeeper causing crashes. */
        attribute id : String = "DM-625";
        attribute connection_limit_enforced : Boolean;
        attribute crashes_prevented : Boolean;
    }

    requirement def UserFriendlyLoadingScript {
        doc /* Create end-to-end loading script for single node with metadata, partitioner, and chunk loading. */
        attribute id : String = "DM-621";
        attribute script_created : Boolean;
        attribute handles_metadata : Boolean;
        attribute runs_partitioner : Boolean;
        attribute loads_chunks : Boolean;
    }

    requirement def ManageConfigAsGlobalVariable {
        doc /* Manage commons.config as global variable similar to logger. */
        attribute id : String = "DM-616";
        attribute managed_as_global : Boolean;
    }

    requirement def RenameQservAdminScript {
        doc /* Rename qserv_admin.py to qserv-admin.py for consistency. */
        attribute id : String = "DM-614";
        attribute script_renamed : Boolean;
    }

    requirement def DocumentAutomatedTestDifferences {
        doc /* Document differences in automated tests after CSS migration. */
        attribute id : String = "DM-613";
        attribute differences_documented : Boolean;
    }

    requirement def RemoveObsoleteQMSCode {
        doc /* Remove obsolete QMS-related code from codebase. */
        attribute id : String = "DM-612";
        attribute qms_code_removed : Boolean;
    }

    requirement def SwitchKazooVersion {
        doc /* Upgrade kazoo from 1.3.1 to 2.0b1 or later. */
        attribute id : String = "DM-611";
        attribute kazoo_upgraded : Boolean;
        attribute min_version : String = "2.0b1";
    }

    requirement def UpdateParseAnalysisTests {
        doc /* Update tests to detect missing css-kvmap early. */
        attribute id : String = "DM-604";
        attribute early_detection_added : Boolean;
    }

    requirement def ReorganizeClientModule {
        doc /* Move client package contents to admin directory. */
        attribute id : String = "DM-597";
        attribute contents_moved : Boolean;
    }

    requirement def FixAutomatedTestsAfterCSSMigration {
        doc /* Fix metadata loading in automated tests after CSS migration. */
        attribute id : String = "DM-596";
        attribute metadata_loading_fixed : Boolean;
    }

    requirement def CleanupIncludesAddModuleName {
        doc /* Add module name to include statements throughout codebase. */
        attribute id : String = "DM-560";
        attribute module_names_added : Boolean;
    }

    requirement def FixSconsRebuildsWithoutChanges {
        doc /* Fix scons rebuilding targets when nothing has changed. */
        attribute id : String = "DM-546";
        attribute unnecessary_rebuilds_fixed : Boolean;
    }

    requirement def QservReturnsErrorTable {
        doc /* Evaluate and potentially change error handling to return mysql error codes instead of diagnostic tables. */
        attribute id : String = "DM-531";
        attribute error_handling_evaluated : Boolean;
    }

    requirement def FixRaceConditionInCreateDb {
        doc /* Fix race condition when creating database in qserv_admin_impl.py. */
        attribute id : String = "DM-516";
        attribute race_condition_fixed : Boolean;
    }

    requirement def SwitchToCzarNameConsistently {
        doc /* Rename master to czar consistently throughout codebase. */
        attribute id : String = "DM-514";
        attribute module_renamed : Boolean;
        attribute library_renamed : Boolean;
        attribute script_renamed : Boolean;
    }

    requirement def TweakMetadataStructure {
        doc /* Clarify and optimize metadata structure for driving table and secondary index. */
        attribute id : String = "DM-510";
        attribute structure_optimized : Boolean;
    }

    requirement def RenameDbGroupToStorageClass {
        doc /* Rename dbGroup to storageClass in CSS metadata. */
        attribute id : String = "DM-509";
        attribute renamed_to_storage_class : Boolean;
    }

    requirement def ShortenInternalZookeeperNames {
        doc /* Shorten internal names in zookeeper for clarity. */
        attribute id : String = "DM-508";
        attribute names_shortened : Boolean;
    }

    requirement def ReworkCSSPythonExceptions {
        doc /* Split CSS exceptions into key-value and db/table categories. */
        attribute id : String = "DM-470";
        attribute exceptions_split : Boolean;
    }

    requirement def ImplementCSSBackupRestore {
        doc /* Implement backup and restore functionality for CSS key/value store. */
        attribute id : String = "DM-460";
        attribute backup_implemented : Boolean;
        attribute restore_implemented : Boolean;
    }

    requirement def WriteLSBCompliantInitScripts {
        doc /* Write Linux Standard Base compliant init.d scripts for Qserv services. */
        attribute id : String = "DM-405";
        attribute scripts_lsb_compliant : Boolean;
    }

    requirement def PackageIntegrationTestsInEups {
        doc /* Create qserv-integration-tests eupspkg for version management. */
        attribute id : String = "DM-365";
        attribute package_created : Boolean;
    }

    requirement def InstallMultipleQservVersions {
        doc /* Enable installation and tagging of multiple Qserv versions on same distserver. */
        attribute id : String = "DM-355";
        attribute multiple_versions_supported : Boolean;
    }

    requirement def RemoveDeadCodeStringUtil {
        doc /* Remove obsolete strToDoubleFunc and related code from stringUtil.h. */
        attribute id : String = "DM-337";
        attribute dead_code_removed : Boolean;
    }

    requirement def CleanupIncludesInQservModules {
        doc /* Cleanup and organize includes in Qserv core modules. */
        attribute id : String = "DM-313";
        attribute includes_cleaned : Boolean;
    }

    requirement def FixMysqldRestartBreaksQserv {
        doc /* Fix qserv becoming unusable after mysqld restart due to cached connections. */
        attribute id : String = "DM-298";
        attribute connection_caching_fixed : Boolean;
    }

    requirement def EliminateQueryAnalysisParserDependence {
        doc /* Remove query analyzer dependence on parser and ANTLR. */
        attribute id : String = "DM-290";
        attribute dependencies_removed : Boolean;
    }

    requirement def FixMetadataExceptionsCrashCzar {
        doc /* Eliminate faulty code causing czar crashes from metadata exceptions. */
        attribute id : String = "DM-282";
        attribute faulty_code_eliminated : Boolean;
    }

    requirement def Log4cxxLoggingPrototypeV2 {
        doc /* Implement log4cxx-based logging prototype v2 with improvements. */
        attribute id : String = "DM-195";
        attribute prototype_implemented : Boolean;
        attribute hierarchical_names_supported : Boolean;
        attribute debug_level_optimization_added : Boolean;
    }

    requirement def NodeConfigurationBootstrappingDesign {
        doc /* Design node configuration and bootstrapping for Qserv components. */
        attribute id : String = "DM-53";
        attribute design_complete : Boolean;
    }

    requirement def QservConfigurationDesign {
        doc /* Design runtime configuration for all Qserv components. */
        attribute id : String = "DM-52";
        attribute design_complete : Boolean;
    }

    requirement def RunSingleSlowWorkerScenario {
        doc /* Run and study single slow worker HTCondor ClassAds scenario with Rank optimization. */
        attribute id : String = "DM-654";
        attribute scenario_executed : Boolean;
        attribute rank_behavior_observed : Boolean;
    }

    requirement def RunBaselineHTCondorScenarios {
        doc /* Run baseline HTCondor ClassAds scenarios to verify Rank-based job placement. */
        attribute id : String = "DM-653";
        attribute scenarios_executed : Boolean;
        attribute rank_placement_verified : Boolean;
    }

    requirement def AddDistributorToSimulatorV2 {
        doc /* Add distributor to simulator demonstrating replicator-distributor interaction. */
        attribute id : String = "DM-561";
        attribute distributor_added : Boolean;
        attribute replicator_associated : Boolean;
        attribute job_info_sent : Boolean;
        attribute data_copied : Boolean;
    }

    requirement def DevelopDataProcessingMonitoring {
        doc /* Develop monitoring for identifying data processed on nodes/slots using HTCondor standards. */
        attribute id : String = "DM-677";
        attribute monitoring_implemented : Boolean;
        attribute uses_startd_history : Boolean;
    }

    requirement def AddArchiveDMCSToSimulatorV3 {
        doc /* Add Archive DMCS to simulator receiving information from duplicator. */
        attribute id : String = "DM-564";
        attribute archive_dmcs_added : Boolean;
        attribute receives_visit_id : Boolean;
        attribute receives_exposure_sequence : Boolean;
        attribute receives_raft_id : Boolean;
        attribute receives_network_address : Boolean;
    }
}