/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * 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 com.android.bedstead.metricsrecorder;

import com.android.bedstead.nene.exceptions.NeneException;
import com.android.queryable.Queryable;
import com.android.queryable.queries.BooleanQuery;
import com.android.queryable.queries.BooleanQueryHelper;
import com.android.queryable.queries.IntegerQuery;
import com.android.queryable.queries.IntegerQueryHelper;
import com.android.queryable.queries.ListQueryHelper;
import com.android.queryable.queries.StringQuery;
import com.android.queryable.queries.StringQueryHelper;

import java.time.Duration;
import java.time.Instant;

public class MetricQueryBuilder implements Queryable {
    private final EnterpriseMetricsRecorder mRecorder;
    private boolean hasStartedFetchingResults = false;
    private int mSkippedNextResults = 0;
    private int mSkippedPollResults = 0;

    private final IntegerQueryHelper<MetricQueryBuilder> mTypeQuery =
            new IntegerQueryHelper<>(this);
    private final StringQueryHelper<MetricQueryBuilder> mAdminPackageNameQuery =
            new StringQueryHelper<>(this);
    private final BooleanQueryHelper<MetricQueryBuilder> mBooleanQuery =
            new BooleanQueryHelper<>(this);
    private final ListQueryHelper<MetricQueryBuilder, String, StringQuery<?>> mStringsQuery =
            new ListQueryHelper<>(this);
    private final IntegerQueryHelper<MetricQueryBuilder> mIntegerQuery =
            new IntegerQueryHelper<>(this);

    MetricQueryBuilder(EnterpriseMetricsRecorder recorder) {
        mRecorder = recorder;
    }

    /** Query for {@link EnterpriseMetricInfo#type()}. */
    public IntegerQuery<MetricQueryBuilder> whereType() {
        if (hasStartedFetchingResults) {
            throw new IllegalStateException("Cannot modify query after fetching results");
        }
        return mTypeQuery;
    }

    /** Query for {@link EnterpriseMetricInfo#adminPackageName()}. */
    public StringQuery<MetricQueryBuilder> whereAdminPackageName() {
        if (hasStartedFetchingResults) {
            throw new IllegalStateException("Cannot modify query after fetching results");
        }
        return mAdminPackageNameQuery;
    }

    /** Query for {@link EnterpriseMetricInfo#Boolean()}. */
    public BooleanQuery<MetricQueryBuilder> whereBoolean() {
        if (hasStartedFetchingResults) {
            throw new IllegalStateException("Cannot modify query after fetching results");
        }
        return mBooleanQuery;
    }

    /** Query for {@link EnterpriseMetricInfo#integer()}. */
    public IntegerQuery<MetricQueryBuilder> whereInteger() {
        if (hasStartedFetchingResults) {
            throw new IllegalStateException("Cannot modify query after fetching results");
        }
        return mIntegerQuery;
    }

    public ListQueryHelper<MetricQueryBuilder, String, StringQuery<?>> whereStrings() {
        if (hasStartedFetchingResults) {
            throw new IllegalStateException("Cannot modify query after fetching results");
        }
        return mStringsQuery;
    }

    public EnterpriseMetricInfo get() {
        return get(/* skipResults= */ 0);
    }

    private EnterpriseMetricInfo get(int skipResults) {
        hasStartedFetchingResults = true;
        for (EnterpriseMetricInfo m : mRecorder.fetchLatestData()) {
            if (matches(m)) {
                skipResults -= 1;
                if (skipResults < 0) {
                    return m;
                }
            }
        }

        return null;
    }

    public EnterpriseMetricInfo next() {
        hasStartedFetchingResults = true;

        EnterpriseMetricInfo nextResult = get(mSkippedNextResults);
        if (nextResult != null) {
            mSkippedNextResults++;
        }

        return nextResult;
    }

    public EnterpriseMetricInfo poll() {
        return poll(Duration.ofSeconds(30));
    }

    public EnterpriseMetricInfo poll(Duration timeout) {
        hasStartedFetchingResults = true;
        Instant endTime = Instant.now().plus(timeout);

        while (Instant.now().isBefore(endTime)) {
            EnterpriseMetricInfo nextResult = get(mSkippedPollResults);
            if (nextResult != null) {
                mSkippedPollResults++;
                return nextResult;
            }

            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                throw new NeneException("Interrupted while polling", e);
            }
        }

        return null;
    }

    private boolean matches(EnterpriseMetricInfo metric) {
        return mAdminPackageNameQuery.matches(metric.adminPackageName())
                && mTypeQuery.matches(metric.type())
                && mBooleanQuery.matches(metric.Boolean())
                && mStringsQuery.matches(metric.strings())
                && mIntegerQuery.matches(metric.integer());
    }

    @Override
    public String describeQuery(String fieldName) {
        return "{" + Queryable.joinQueryStrings(
                mAdminPackageNameQuery.describeQuery("adminPackageName"),
                mTypeQuery.describeQuery("type"),
                mBooleanQuery.describeQuery("boolean"),
                mStringsQuery.describeQuery("strings"),
                mIntegerQuery.describeQuery("integer")
        ) + "}";
    }

    @Override
    public String toString() {
        return describeQuery("");
    }
}
