/*
 * Copyright 2015-present 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.config.basics;

import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.HostId;
import org.onosproject.net.LinkKey;
import org.onosproject.net.config.SubjectFactory;
import org.onosproject.net.region.RegionId;

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

/**
 * Set of subject factories for potential configuration subjects.
 */
public final class SubjectFactories {

    // Construction forbidden
    private SubjectFactories() {
    }

    // Required for resolving application identifiers
    private static CoreService coreService;

    /**
     * Application ID subject factory.
     */
    public static final SubjectFactory<ApplicationId> APP_SUBJECT_FACTORY =
            new SubjectFactory<ApplicationId>(ApplicationId.class, "apps") {
                @Override
                public ApplicationId createSubject(String key) {
                    return coreService.registerApplication(key);
                }

                @Override
                public String subjectKey(ApplicationId subject) {
                    return subject.name();
                }
            };

    /**
     * Device ID subject factory.
     */
    public static final SubjectFactory<DeviceId> DEVICE_SUBJECT_FACTORY =
            new SubjectFactory<DeviceId>(DeviceId.class, "devices") {
                @Override
                public DeviceId createSubject(String key) {
                    return DeviceId.deviceId(key);
                }
            };

    /**
     * Connect point subject factory.
     */
    public static final SubjectFactory<ConnectPoint> CONNECT_POINT_SUBJECT_FACTORY =
            new SubjectFactory<ConnectPoint>(ConnectPoint.class, "ports") {
                @Override
                public ConnectPoint createSubject(String key) {
                    return ConnectPoint.deviceConnectPoint(key);
                }

                @Override
                public String subjectKey(ConnectPoint subject) {
                    return key(subject);
                }
            };

    /**
     * Host ID subject factory.
     */
    public static final SubjectFactory<HostId> HOST_SUBJECT_FACTORY =
            new SubjectFactory<HostId>(HostId.class, "hosts") {
                @Override
                public HostId createSubject(String key) {
                    return HostId.hostId(key);
                }
            };

    /**
     * Link key subject factory.
     */
    public static final SubjectFactory<LinkKey> LINK_SUBJECT_FACTORY =
            new SubjectFactory<LinkKey>(LinkKey.class, "links") {
                @Override
                public LinkKey createSubject(String key) {
                    String[] cps = key.split("-");
                    checkArgument(cps.length == 2, "Incorrect link key format: %s", key);
                    return LinkKey.linkKey(ConnectPoint.deviceConnectPoint(cps[0]),
                            ConnectPoint.deviceConnectPoint(cps[1]));
                }

                @Override
                public String subjectKey(LinkKey subject) {
                    return key(subject.src()) + "-" + key(subject.dst());
                }
            };

    /**
     * Region ID subject factory.
     */
    public static final SubjectFactory<RegionId> REGION_SUBJECT_FACTORY =
            new SubjectFactory<RegionId>(RegionId.class, "regions") {
                @Override
                public RegionId createSubject(String key) {
                    return RegionId.regionId(key);
                }
            };

    /**
     * Provides reference to the core service, which is required for
     * application subject factory.
     *
     * @param service core service reference
     */
    public static void setCoreService(CoreService service) {
        coreService = service;
    }

    private static String key(ConnectPoint subject) {
        return subject.deviceId() + "/" + subject.port();
    }

}
