/*
 * Copyright 2018-present Open Networking Foundation
 *
 * 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.pipelines.fabric.pro;

import com.google.common.collect.ImmutableList;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onosproject.net.behaviour.Pipeliner;
import org.onosproject.net.device.PortStatisticsDiscovery;
import org.onosproject.net.pi.model.DefaultPiPipeconf;
import org.onosproject.net.pi.model.PiPipeconf;
import org.onosproject.net.pi.model.PiPipeconfId;
import org.onosproject.net.pi.model.PiPipelineInterpreter;
import org.onosproject.net.pi.model.PiPipelineModel;
import org.onosproject.net.pi.service.PiPipeconfService;
import org.onosproject.p4runtime.model.P4InfoParser;
import org.onosproject.p4runtime.model.P4InfoParserException;
import org.onosproject.pipelines.fabric.FabricInterpreter;
import org.onosproject.pipelines.fabric.FabricPortStatisticsDiscovery;
import org.onosproject.pipelines.fabric.pipeliner.FabricPipeliner;

import java.net.URL;
import java.util.Collection;

import static java.lang.String.format;
import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.P4_INFO_TEXT;
import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.TOFINO_BIN;
import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.TOFINO_CONTEXT_JSON;
import static org.onosproject.pipelines.fabric.PipeconfLoader.FABRIC_PIPECONF_ID;

/**
 * Pipeline config loader for fabric pipeline.
 */
@Component(immediate = true)
public class HwPipeconfLoader {

    private static final String MAVERICKS = "mavericks";
    private static final String MONTANA = "montana";

    private static final String PLAIN_FABRIC = "";
    private static final String WITH_SPGW = "-spgw";

    // TODO: add WITH_SPGW when ready
    private static final Collection<String> APPENDICES = ImmutableList
            .of(PLAIN_FABRIC, WITH_SPGW);

    private static final Collection<String> PLATFORMS = ImmutableList
            .of(MAVERICKS, MONTANA);

    private static final String BASE_PATH = "/p4c-out/tofino/fabric%s/%s";
    private static final String BASE_TOFINO_BIN_PATH = BASE_PATH + "/tofino.bin";
    private static final String BASE_CONTEXT_JSON_PATH = BASE_PATH + "/context.json";
    private static final String BASE_P4INFO_PATH = BASE_PATH + "/fabric.p4info";

    private static final Collection<PiPipeconf> ALL_PIPECONFS = buildAll();

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    private PiPipeconfService piPipeconfService;

    @Activate
    public void activate() {
        // Registers all pipeconf at component activation.
        ALL_PIPECONFS.forEach(piPipeconfService::register);
    }

    @Deactivate
    public void deactivate() {
        ALL_PIPECONFS.stream().map(PiPipeconf::id).forEach(piPipeconfService::remove);
    }

    private static PiPipeconf buildTofinoPipeconf(String platform, String appendix) {
        final PiPipeconfId pipeconfId = new PiPipeconfId(
                FABRIC_PIPECONF_ID.id() + appendix + "." + platform);
        final URL tofinoBinUrl = HwPipeconfLoader.class
                .getResource(format(BASE_TOFINO_BIN_PATH, appendix, platform));
        final URL contextJsonUrl = HwPipeconfLoader.class
                .getResource(format(BASE_CONTEXT_JSON_PATH, appendix, platform));
        final URL p4InfoUrl = HwPipeconfLoader.class
                .getResource(format(BASE_P4INFO_PATH, appendix, platform));

        final PiPipelineModel model = parseP4Info(p4InfoUrl);
        return DefaultPiPipeconf.builder()
                .withId(pipeconfId)
                .withPipelineModel(model)
                .addBehaviour(PiPipelineInterpreter.class, FabricInterpreter.class)
                .addBehaviour(Pipeliner.class, FabricPipeliner.class)
                .addBehaviour(PortStatisticsDiscovery.class, FabricPortStatisticsDiscovery.class)
                .addExtension(P4_INFO_TEXT, p4InfoUrl)
                .addExtension(TOFINO_BIN, tofinoBinUrl)
                .addExtension(TOFINO_CONTEXT_JSON, contextJsonUrl)
                .build();
    }

    private static Collection<PiPipeconf> buildAll() {
        ImmutableList.Builder<PiPipeconf> builder = ImmutableList.builder();
        for (String platform : PLATFORMS) {
            for (String appendix : APPENDICES) {
                builder.add(buildTofinoPipeconf(platform, appendix));
            }
        }
        return builder.build();
    }

    private static PiPipelineModel parseP4Info(URL p4InfoUrl) {
        try {
            return P4InfoParser.parse(p4InfoUrl);
        } catch (P4InfoParserException e) {
            throw new RuntimeException(e);
        }
    }
}
