# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
from rules.helpers import deployed_helper
from com.xebialabs.deployit.plugin.api.deployment.planning import Checkpoint

helper = deployed_helper(previousDeployed, steps)
checkpoints = delta.intermediateCheckpoints


def should_execute_script(fname):
    is_checkpointed = helper.extract_checkpointname(fname) in checkpoints
    return not checkpoints or is_checkpointed


#list_create_scripts()
all_script_files = [
    ff for ff in helper.list_rollback_scripts() if should_execute_script(ff)
]
# Sort reverse alphabetically
all_script_files.sort(reverse=True)

last_step = None
for script_file in all_script_files:
    last_step = helper.destroy_script_step(script_file)
    checkpoint = Checkpoint(delta._delegate,
                            helper.extract_checkpointname(script_file), None)
    context.addStepWithCheckpoint(last_step, checkpoint)

if last_step:
    context.addCheckpoint(last_step, delta._delegate)
current_files = helper.list_create_scripts()
previous_files = previous_helper.list_create_scripts()
current_set = Set(current_files)
previous_set = Set(previous_files)

check_contents = previous_helper.deployed.executeModifiedScripts and previous_helper.deployed.executeRollbackForModifiedScripts
missing_scripts = list(difference(previous_set, current_set, check_contents, previous_helper, helper))
# Reverse sort, as we're going to roll these back.
missing_scripts.sort(reverse=True)

last_step = None
for missing_script in missing_scripts:
    rollback_script = previous_helper.rollback_script_for(missing_script)
    if rollback_script:
        last_step = previous_helper.destroy_script_step(rollback_script, previous_helper.deployed.modifyOptions)
        checkpoint = Checkpoint(delta._delegate, helper.extract_checkpointname(missing_script), Operation.DESTROY)
        context.addStepWithCheckpoint(last_step, checkpoint)

check_contents = helper.deployed.executeModifiedScripts
new_scripts = list(difference(current_set, previous_set, check_contents, helper, previous_helper))
# Sort in ascending order.
new_scripts.sort()

for new_script in new_scripts:
    last_step = helper.create_script_step(new_script, helper.deployed.modifyOptions)
    checkpoint = Checkpoint(delta._delegate, helper.extract_checkpointname(new_script), Operation.CREATE)
    context.addStepWithCheckpoint(last_step, checkpoint)

if last_step:
    context.addCheckpoint(last_step, delta._delegate)