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

import com.google.common.base.MoreObjects;
import org.onosproject.openstacknode.api.OpenstackAuth;

import java.util.Objects;

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

public class DefaultOpenstackAuth implements OpenstackAuth {

    private final String version;
    private final Integer port;
    private final Protocol protocol;
    private final String username;
    private final String password;
    private final String project;
    private final Perspective perspective;

    private static final String NOT_NULL_MSG = "% cannot be null";

    /**
     * A default constructor of keystone authentication instance.
     *
     * @param version       version number
     * @param port          endpoint port number
     * @param protocol      endpoint protocol type
     * @param username      keystone username
     * @param password      keystone password
     * @param project       project name
     * @param perspective   user perspective
     */
    protected DefaultOpenstackAuth(String version, Integer port, Protocol protocol,
                                   String username, String password, String project,
                                   Perspective perspective) {

        this.version = version;
        this.port = port;
        this.protocol = protocol;
        this.username = username;
        this.password = password;
        this.project = project;
        this.perspective = perspective;
    }

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

    @Override
    public Integer port() {
        return port;
    }

    @Override
    public Protocol protocol() {
        return protocol;
    }

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

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

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

    @Override
    public Perspective perspective() {
        return perspective;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (obj instanceof DefaultOpenstackAuth) {
            DefaultOpenstackAuth that = (DefaultOpenstackAuth) obj;
            return Objects.equals(version, that.version) &&
                    Objects.equals(port, that.port) &&
                    Objects.equals(protocol, that.protocol) &&
                    Objects.equals(username, that.username) &&
                    Objects.equals(password, that.password) &&
                    Objects.equals(project, that.project) &&
                    Objects.equals(perspective, that.perspective);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(version,
                port,
                protocol,
                username,
                password,
                project,
                perspective);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("version", version)
                .add("port", port)
                .add("protocol", protocol)
                .add("username", username)
                .add("password", password)
                .add("project", project)
                .add("perspective", perspective)
                .toString();
    }

    /**
     * Returns new builder instance.
     *
     * @return keystone authentication instance builder
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * A builder class for openstack authentication.
     */
    public static final class Builder implements OpenstackAuth.Builder {

        private String version;
        private Integer port;
        private Protocol protocol;
        private String username;
        private String password;
        private String project;
        private Perspective perspective;

        // private constructor not intended to use from external
        private Builder() {
        }

        @Override
        public OpenstackAuth build() {
            checkArgument(version != null, NOT_NULL_MSG, "version");
            checkArgument(port != null, NOT_NULL_MSG, "port");
            checkArgument(protocol != null, NOT_NULL_MSG, "protocol");
            checkArgument(username != null, NOT_NULL_MSG, "username");
            checkArgument(password != null, NOT_NULL_MSG, "password");
            checkArgument(project != null, NOT_NULL_MSG, "project");

            return new DefaultOpenstackAuth(version,
                    port,
                    protocol,
                    username,
                    password,
                    project,
                    perspective);
        }

        @Override
        public Builder version(String version) {
            this.version = version;
            return this;
        }

        @Override
        public Builder port(Integer port) {
            this.port = port;
            return this;
        }

        @Override
        public Builder protocol(Protocol protocol) {
            this.protocol = protocol;
            return this;
        }

        @Override
        public Builder username(String username) {
            this.username = username;
            return this;
        }

        @Override
        public Builder password(String password) {
            this.password = password;
            return this;
        }

        @Override
        public Builder project(String project) {
            this.project = project;
            return this;
        }

        @Override
        public Builder perspective(Perspective perspective) {
            this.perspective = perspective;
            return this;
        }
    }
}
