/*
 * Copyright 2015 Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.onosproject.net.intent.impl.phase;

import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentData;
import org.onosproject.net.intent.IntentException;
import org.onosproject.net.intent.impl.IntentProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Optional;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Represents a phase where an intent is being compiled or recompiled.
 */
class Compiling implements IntentProcessPhase {

    private static final Logger log = LoggerFactory.getLogger(Compiling.class);

    private final IntentProcessor processor;
    private final IntentData data;
    private final Optional<IntentData> stored;

    /**
     * Creates a intent recompiling phase.
     *
     * @param processor intent processor that does work for recompiling
     * @param data      intent data containing an intent to be recompiled
     * @param stored    intent data stored in the store
     */
    Compiling(IntentProcessor processor, IntentData data, Optional<IntentData> stored) {
        this.processor = checkNotNull(processor);
        this.data = checkNotNull(data);
        this.stored = checkNotNull(stored);
    }

    @Override
    public Optional<IntentProcessPhase> execute() {
        try {
            List<Intent> compiled = processor.compile(data.intent(),
                    //TODO consider passing an optional here in the future
                    stored.isPresent() ? stored.get().installables() : null);
            return Optional.of(new Installing(processor, new IntentData(data, compiled), stored));
        } catch (IntentException e) {
            log.debug("Unable to compile intent {} due to: {}", data.intent(), e);
            if (stored.isPresent() && !stored.get().installables().isEmpty()) {
                // removing orphaned flows and deallocating resources
                return Optional.of(new Withdrawing(processor, new IntentData(data, stored.get().installables())));
            } else {
                return Optional.of(new Failed(data));
            }
        }
    }
}
