/*
 * Copyright 2016-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.nemo.model.intent;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import static com.google.common.base.MoreObjects.toStringHelper;

/**
 * Representation of register user output builder.
 */
public class RegisterUserOutputBuilder extends DefaultOutputBuilderBase {

    private Map<Class<? extends RegisterUserOutput>, RegisterUserOutput>
            augmentation = new HashMap<>();

    public RegisterUserOutputBuilder() {
    }

    /**
     * Constructs the register user output builder from a result code.
     *
     * @param rpc common RPC result
     */
    public RegisterUserOutputBuilder(CommonRpcResult rpc) {
        resultCode = rpc.getResultCode();
        message = rpc.getMessage();
    }

    /**
     * Constructs register user output builder.
     *
     * @param base register user output object
     */
    public RegisterUserOutputBuilder(RegisterUserOutput base) {
        message = base.getMessage();
        resultCode = base.getResultCode();
        if (base instanceof RegisterUserOutputImpl) {
            RegisterUserOutputImpl impl = (RegisterUserOutputImpl) base;
            if (!impl.augmentation.isEmpty()) {
                augmentation = new HashMap<>(impl.augmentation);
            }
        }
    }

    /**
     * Adds augmentation by a class type and a register user output.
     * If the augmentation is null, remove the augmentation type key
     * from the hash map.
     *
     * @param augmentationType type that extends RegisterUserOutput
     * @param augmentation register user output object
     * @return self
     */
    public RegisterUserOutputBuilder addAugmentation(
            Class<? extends RegisterUserOutput> augmentationType,
            RegisterUserOutput augmentation) {
        if (augmentation == null) {
            return removeAugmentation(augmentationType);
        }
        this.augmentation.put(augmentationType, augmentation);
        return this;
    }

    /**
     * Removes augmentation by a class type.
     *
     * @param augmentationType type that extends RegisterUserOutput
     * @return self
     */
    public RegisterUserOutputBuilder removeAugmentation(
            Class<? extends RegisterUserOutput> augmentationType) {
        augmentation.remove(augmentationType);
        return this;
    }

    /**
     * Builds a register user output object.
     *
     * @return the register user output object
     */
    public RegisterUserOutput build() {
        return new RegisterUserOutputImpl(this);
    }

    /**
     * Representation of the implement of RegisterUserOutput.
     */
    private static final class RegisterUserOutputImpl
            extends DefaultOutputImplBase
            implements RegisterUserOutput {

        private final Map<Class<? extends RegisterUserOutput>, RegisterUserOutput>
                augmentation;

        private RegisterUserOutputImpl(RegisterUserOutputBuilder base) {
            message = base.message;
            resultCode = base.resultCode;
            augmentation = new HashMap<>(base.augmentation);
        }

        @Override
        public int hashCode() {
            return Objects.hash(message, resultCode, augmentation);
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            RegisterUserOutputImpl other = (RegisterUserOutputImpl) obj;
            return Objects.equals(message, other.getMessage()) &&
                    Objects.equals(resultCode, other.getResultCode()) &&
                    Objects.equals(augmentation, other.augmentation);
        }

        @Override
        public String toString() {
            return toStringHelper(this)
                    .add("message", message)
                    .add("resultCode", resultCode)
                    .add("augmentation", augmentation).toString();
        }
    }
}