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

import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import org.onosproject.core.ApplicationId;

import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * Key class for Intents.
 */
// TODO maybe pull this up to utils
public abstract class Key {

    //TODO consider making this a HashCode object (worry about performance)
    private final long hash;
    private static final HashFunction HASH_FN = Hashing.md5();

    protected Key(long hash) {
        this.hash = hash;
    }

    public long hash() {
        return hash;
    }

    @Override
    public int hashCode() {
        return (int) (hash() ^ (hash() >>> 32));
    }

    @Override
    public abstract boolean equals(Object obj);

    /**
     * Creates a key based on the provided string.
     * <p>
     * Note: Two keys with equal value, but different appId, are not equal.
     * </p>
     *
     * @param key the provided string
     * @param appId application id to associate with this key
     * @return the key for the string
     */
    public static Key of(String key, ApplicationId appId) {
        return new StringKey(key, appId);
    }

    /**
     * Creates a key based on the provided long.
     * <p>
     * Note: Two keys with equal value, but different appId, are not equal.
     * Also, "10" and 10L are different.
     * </p>
     *
     * @param key the provided long
     * @param appId application id to associate with this key
     * @return the key for the long
     */
    public static Key of(long key, ApplicationId appId) {
        return new LongKey(key, appId);
    }

    private static final class StringKey extends Key {

        private final ApplicationId appId;
        private final String key;

        private StringKey(String key, ApplicationId appId) {
            super(HASH_FN.newHasher()
                          .putShort(appId.id())
                          .putString(key, StandardCharsets.UTF_8)
                          .hash().asLong());
            this.key = key;
            this.appId = appId;
        }

        @Override
        public String toString() {
            return key;
        }

        // checkstyle requires this
        @Override
        public int hashCode() {
            return super.hashCode();
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null || getClass() != obj.getClass()) {
                return false;
            }
            final StringKey other = (StringKey) obj;
            return this.hash() == other.hash() &&
                    Objects.equals(this.appId, other.appId) &&
                    Objects.equals(this.key, other.key);
        }
    }

    private static final class LongKey extends Key {

        private final ApplicationId appId;
        private final long key;

        private LongKey(long key, ApplicationId appId) {
            super(HASH_FN.newHasher()
                          .putShort(appId.id())
                          .putLong(key)
                          .hash().asLong());
            this.key = key;
            this.appId = appId;
        }

        @Override
        public String toString() {
            return "0x" + Long.toHexString(key);
        }

        // checkstyle requires this
        @Override
        public int hashCode() {
            return super.hashCode();
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null || getClass() != obj.getClass()) {
                return false;
            }
            final LongKey other = (LongKey) obj;
            return this.hash() == other.hash() &&
                    this.key == other.key &&
                    Objects.equals(this.appId, other.appId);
        }
    }
}


