/*
 * 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.core;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.onosproject.security.Permission;

import java.net.URI;
import java.util.Set;
import java.util.Optional;
import java.util.List;
import java.util.Objects;

import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Default implementation of network control/management application descriptor.
 */
public class DefaultApplication implements Application {

    private final ApplicationId appId;
    private final Version version;
    private final String description;
    private final String category;
    private final String url;
    private final String readme;
    private final byte[] icon;
    private final String origin;
    private final ApplicationRole role;
    private final Set<Permission> permissions;
    private final Optional<URI> featuresRepo;
    private final List<String> features;
    private final List<String> requiredApps;

    /**
     * Creates a new application descriptor using the supplied data.
     *
     * @param appId        application identifier
     * @param version      application version
     * @param description  application description
     * @param origin       origin company
     * @param category     application category
     * @param url          application URL
     * @param readme       application readme
     * @param icon         application icon
     * @param role         application role
     * @param permissions  requested permissions
     * @param featuresRepo optional features repo URI
     * @param features     application features
     * @param requiredApps list of required application names
     */
    public DefaultApplication(ApplicationId appId, Version version,
                              String description, String origin, String category,
                              String url, String readme, byte[] icon,
                              ApplicationRole role, Set<Permission> permissions,
                              Optional<URI> featuresRepo, List<String> features,
                              List<String> requiredApps) {
        this.appId = checkNotNull(appId, "ID cannot be null");
        this.version = checkNotNull(version, "Version cannot be null");
        this.description = checkNotNull(description, "Description cannot be null");
        this.origin = checkNotNull(origin, "Origin cannot be null");
        this.category = checkNotNull(category, "Category cannot be null");
        this.url = url;
        this.readme = checkNotNull(readme, "Readme cannot be null");
        this.icon = icon == null ? new byte[0] : icon.clone();
        this.role = checkNotNull(role, "Role cannot be null");
        this.permissions = ImmutableSet.copyOf(
                checkNotNull(permissions, "Permissions cannot be null")
        );
        this.featuresRepo = checkNotNull(featuresRepo, "Features repo cannot be null");
        this.features = ImmutableList.copyOf(
                checkNotNull(features, "Features cannot be null")
        );
        this.requiredApps = ImmutableList.copyOf(
                checkNotNull(requiredApps, "Required apps cannot be null")
        );
        checkArgument(!features.isEmpty(), "There must be at least one feature");
    }

    @Override
    public ApplicationId id() {
        return appId;
    }

    @Override
    public Version version() {
        return version;
    }

    @Override
    public String description() {
        return description;
    }

    @Override
    public String category() {
        return category;
    }

    @Override
    public String url() {
        return url;
    }

    @Override
    public String readme() {
        return readme;
    }

    @Override
    public byte[] icon() {
        return icon.clone();
    }

    @Override
    public String origin() {
        return origin;
    }

    @Override
    public ApplicationRole role() {
        return role;
    }

    @Override
    public Set<Permission> permissions() {
        return permissions;
    }

    @Override
    public Optional<URI> featuresRepo() {
        return featuresRepo;
    }

    @Override
    public List<String> features() {
        return features;
    }

    @Override
    public List<String> requiredApps() {
        return requiredApps;
    }

    @Override
    public int hashCode() {
        return Objects.hash(appId, version, description, origin, category, url,
                            readme, role, permissions, featuresRepo, features, requiredApps);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        final DefaultApplication other = (DefaultApplication) obj;
        return Objects.equals(this.appId, other.appId) &&
                Objects.equals(this.version, other.version) &&
                Objects.equals(this.description, other.description) &&
                Objects.equals(this.origin, other.origin) &&
                Objects.equals(this.category, other.category) &&
                Objects.equals(this.url, other.url) &&
                Objects.equals(this.readme, other.readme) &&
                Objects.equals(this.role, other.role) &&
                Objects.equals(this.permissions, other.permissions) &&
                Objects.equals(this.featuresRepo, other.featuresRepo) &&
                Objects.equals(this.features, other.features) &&
                Objects.equals(this.requiredApps, other.requiredApps);
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("appId", appId)
                .add("version", version)
                .add("description", description)
                .add("origin", origin)
                .add("category", category)
                .add("url", url)
                .add("readme", readme)
                .add("role", role)
                .add("permissions", permissions)
                .add("featuresRepo", featuresRepo)
                .add("features", features)
                .add("requiredApps", requiredApps)
                .toString();
    }
}
