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

import com.google.common.base.MoreObjects;
import com.google.common.collect.DiscreteDomain;
import com.google.common.collect.Range;
import com.google.common.collect.RangeSet;
import com.google.common.collect.TreeRangeSet;
import org.onlab.util.Tools;
import org.onosproject.net.resource.DiscreteResource;
import org.onosproject.net.resource.DiscreteResourceCodec;
import org.onosproject.net.resource.DiscreteResourceId;
import org.onosproject.net.resource.Resources;

import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

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

/**
 * Represents discrete resources encoded by a codec.
 */
final class EncodedDiscreteResources {
    private final RangeSet<Integer> rangeSet;
    private final DiscreteResourceCodec codec;

    EncodedDiscreteResources(RangeSet<Integer> rangeSet, DiscreteResourceCodec codec) {
        this.rangeSet = rangeSet;
        this.codec = codec;
    }

    static EncodedDiscreteResources of(Set<DiscreteResource> resources, DiscreteResourceCodec codec) {
        RangeSet<Integer> rangeSet = TreeRangeSet.create();
        resources.stream()
                .map(x -> x.valueAs(Object.class))
                .flatMap(Tools::stream)
                .map(x -> codec.encode(x))
                .map(Range::singleton)
                .map(x -> x.canonical(DiscreteDomain.integers()))
                .forEach(rangeSet::add);

        return new EncodedDiscreteResources(rangeSet, codec);
    }

    RangeSet<Integer> rangeSet() {
        return rangeSet;
    }

    DiscreteResourceCodec codec() {
        return codec;
    }

    Set<DiscreteResource> values(DiscreteResourceId parent) {
        return rangeSet.asRanges().stream()
                .flatMapToInt(x1 -> IntStream.range(x1.lowerEndpoint(), x1.upperEndpoint()))
                .boxed()
                .map(x -> codec.decode(x))
                .map(x -> Resources.discrete(parent, x).resource())
                .collect(Collectors.toCollection(LinkedHashSet::new));
    }

    Class<?> encodedClass() {
        Range<Integer> firstRange = rangeSet.asRanges().iterator().next();
        return codec.decode(firstRange.lowerEndpoint()).getClass();
    }

    @SuppressWarnings("unchecked")
    boolean contains(DiscreteResource resource) {
        return resource.valueAs(Object.class)
                .map(x -> codec.encode(x))
                .map(rangeSet::contains)
                .orElse(false);
    }

    EncodedDiscreteResources difference(EncodedDiscreteResources other) {
        checkArgument(this.codec.getClass() == other.codec.getClass());

        RangeSet<Integer> newRangeSet = TreeRangeSet.create(this.rangeSet);
        newRangeSet.removeAll(other.rangeSet);

        return new EncodedDiscreteResources(newRangeSet, this.codec);
    }

    EncodedDiscreteResources add(EncodedDiscreteResources other) {
        checkArgument(this.codec.getClass() == other.codec.getClass());

        RangeSet<Integer> newRangeSet = TreeRangeSet.create(this.rangeSet);
        newRangeSet.addAll(other.rangeSet);

        return new EncodedDiscreteResources(newRangeSet, this.codec);
    }

    boolean isEmpty() {
        return rangeSet.isEmpty();
    }

    @Override
    public int hashCode() {
        return Objects.hash(rangeSet, codec);
    }

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

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                .add("rangeSet", rangeSet)
                .add("codec", codec)
                .toString();
    }
}
