// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package io.v.rx.syncbase;

import android.content.Context;

import com.google.common.collect.ImmutableList;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;

import io.v.baku.toolkit.BakuActivityTrait;
import io.v.baku.toolkit.VAndroidContextTrait;
import io.v.baku.toolkit.blessings.BlessingsUtils;
import io.v.baku.toolkit.blessings.ClientUser;
import io.v.v23.context.VContext;
import io.v.v23.security.Blessings;
import io.v.v23.security.access.AccessList;
import io.v.v23.security.access.Permissions;
import io.v.v23.services.syncbase.nosql.SyncgroupMemberInfo;
import io.v.v23.services.syncbase.nosql.SyncgroupSpec;
import io.v.v23.services.syncbase.nosql.TableRow;
import java8.util.function.Function;
import java8.util.function.Supplier;
import java8.util.stream.Collectors;
import lombok.Value;
import lombok.experimental.Accessors;
import rx.Observable;
import rx.functions.Action2;

// TODO(rosswang): Generalize this to other possible syncgroup strategies.
@Accessors(prefix = "m")
public abstract class UserSyncgroup extends RxSyncgroup {
    public static final SgSuffixFormat<Parameters> DEFAULT_SYNCGROUP_SUFFIX =
            SgSuffixFormats.discriminated("user");

    public static class Builder {
        protected VContext mVContext;
        protected Observable<Blessings> mRxBlessings;
        protected SyncHostLevel mSyncHostLevel;
        protected SgSuffixFormat<? super Parameters> mSgSuffixFormat =
                DEFAULT_SYNCGROUP_SUFFIX;
        protected RxDb mDb;
        protected Function<String, String> mDescriptionForUsername = u -> "User syncgroup for " + u;
        protected Function<AccessList, Permissions> mPermissionsForAcl;
        protected List<TableRow> mPrefixes = new ArrayList<>();
        protected SyncgroupMemberInfo mMemberInfo = DEFAULT_SYNCGROUP_MEMBER_INFO;
        protected Action2<Integer, Throwable> mOnError;

        // helper for constructing a default UserAppSyncHost if needed
        protected Context mAndroidContext;

        public Builder vContext(final VContext vContext) {
            mVContext = vContext;
            return this;
        }

        public Builder rxBlessings(final Observable<Blessings> rxBlessings) {
            mRxBlessings = rxBlessings;
            return this;
        }

        public Builder syncHostLevel(final SyncHostLevel syncHostLevel) {
            mSyncHostLevel = syncHostLevel;
            mAndroidContext = null;
            return this;
        }

        public Builder sgSuffixFormat(final SgSuffixFormat sgSuffixFormat) {
            mSgSuffixFormat = sgSuffixFormat;
            return this;
        }

        public Builder sgSuffix(final String sgSuffix) {
            return sgSuffixFormat(SgSuffixFormats.simple(sgSuffix));
        }

        public Builder discriminatedSgSuffix(final String customSuffix) {
            return sgSuffixFormat(SgSuffixFormats.discriminated(customSuffix));
        }

        public Builder db(final RxDb db) {
            mDb = db;
            return this;
        }

        public Builder descriptionForUsername(
                final Function<String, String> descriptionForUsername) {
            mDescriptionForUsername = descriptionForUsername;
            return this;
        }

        public Builder permissionsForAcl(
                final Function<AccessList, Permissions> permissionsForAcl) {
            mPermissionsForAcl = permissionsForAcl;
            return this;
        }

        /**
         * This setter is not additive.
         */
        public Builder prefixes(final List<TableRow> prefixes) {
            mPrefixes.clear();
            mPrefixes.addAll(prefixes);
            return this;
        }

        /**
         * This setter is not additive.
         */
        public Builder prefixes(final TableRow... prefixes) {
            mPrefixes.clear();
            mPrefixes.addAll(Arrays.asList(prefixes));
            return this;
        }

        /**
         * This is an additive setter.
         */
        public Builder prefix(final TableRow prefix) {
            mPrefixes.add(prefix);
            return this;
        }

        /**
         * This is an additive setter.
         */
        public Builder prefix(final String tableName, final String rowPrefix) {
            return prefix(new TableRow(tableName, rowPrefix));
        }

        /**
         * This is an additive setter.
         */
        public Builder prefix(final String tableName) {
            return prefix(tableName, "");
        }

        public Builder memberInfo(final SyncgroupMemberInfo memberInfo) {
            mMemberInfo = memberInfo;
            return this;
        }

        public Builder onError(final Action2<Integer, Throwable> onError) {
            mOnError = onError;
            return this;
        }

        /**
         * This is a composite setter for:
         * <ul>
         * <li>{@code vContext}</li>Context
         * <li>{@code rxBlessings}</li>
         * <li>{@code onError}</li>
         * </ul>
         * and should be called prior to any overrides for those fields.
         */
        public Builder activity(final VAndroidContextTrait<?> t) {
            mAndroidContext = t.getAndroidContext();
            return vContext(t.getVContext())
                    .rxBlessings(t.getBlessingsProvider().getRxBlessings())
                    .onError(t.getErrorReporter()::onError);
        }

        /**
         * In addition to those fields in {@link #activity(VAndroidContextTrait)}, this
         * additionally sets:
         * <ul>
         * <li>{@code db}</li>
         * <li>and adds to {@code prefixes}</li>
         * </ul>
         */
        public Builder activity(final BakuActivityTrait<?> t) {
            return activity(t.getVAndroidContextTrait())
                    .db(t.getSyncbaseDb())
                    .prefix(t.getSyncbaseTableName());
        }

        protected Parameters buildParameters(
                final Supplier<SyncHostLevel> defaultSyncHost,
                final Function<AccessList, Permissions> defaultPermissionsForAcl) {
            return new Parameters(mVContext, mRxBlessings,
                    mSyncHostLevel == null ? defaultSyncHost.get() : mSyncHostLevel,
                    mSgSuffixFormat, mDb, mDescriptionForUsername,
                    mPermissionsForAcl == null? defaultPermissionsForAcl : mPermissionsForAcl,
                    ImmutableList.copyOf(mPrefixes), mMemberInfo, mOnError);
        }

        public UserCloudSyncgroup buildCloud() {
            return new UserCloudSyncgroup(buildParameters(
                    () -> ClientLevelCloudSync.DEFAULT,
                    acl -> BlessingsUtils.cloudSyngroupPermissions(acl,
                            UserCloudSyncgroup.DEBUG_SG_HOST_BLESSING)));
        }

        public UserPeerSyncgroup buildPeer() {
            return new UserPeerSyncgroup(buildParameters(
                    () -> new UserAppSyncHost(mAndroidContext),
                    BlessingsUtils::syncgroupPermissions));
        }
    }

    public static Builder builder() {
        return new Builder();
    }

    @Value
    public static class Parameters {
        VContext mVContext;
        Observable<Blessings> mRxBlessings;
        SyncHostLevel mSyncHostLevel;
        SgSuffixFormat<? super Parameters> mSgSuffixFormat;
        RxDb mDb;
        Function<String, String> mDescriptionForUsername;
        Function<AccessList, Permissions> mPermissionsForAcl;
        ImmutableList<TableRow> mPrefixes;
        SyncgroupMemberInfo mMemberInfo;
        Action2<Integer, Throwable> mOnError;
    }

    protected final Parameters mParams;

    public UserSyncgroup(final Parameters params) {
        super(params.getOnError());
        mParams = params;
    }

    private SyncgroupSpec createSpec(final ClientUser clientUser, final AccessList acl) {
        return new SyncgroupSpec(
                mParams.getDescriptionForUsername().apply(clientUser.getUsername()),
                mParams.getPermissionsForAcl().apply(acl), mParams.getPrefixes(),
                mParams.getSyncHostLevel().getRendezvousTableNames(clientUser), false);
    }

    protected abstract Observable<?> rxJoin(final String sgHost, final String sgName,
                                            final SyncgroupSpec spec);

    private Observable<?> rxJoin(final ClientUser clientUser, final AccessList acl) {
        final String sgHost = mParams.getSyncHostLevel().getSyncgroupHostName(clientUser);
        final String sgName = RxSyncbase.syncgroupName(sgHost,
                mParams.getSgSuffixFormat().get(mParams));
        final SyncgroupSpec spec = createSpec(clientUser, acl);

        return rxJoin(sgHost, sgName, spec);
    }

    @Override
    public Observable<?> rxJoin() {
        return Observable.switchOnNext(mParams.getRxBlessings()
                .map(b -> {
                    final AccessList acl = BlessingsUtils.blessingsToAcl(mParams.getVContext(), b);
                    final List<Observable<?>> joins =
                            BlessingsUtils.blessingsToClientUserStream(mParams.getVContext(), b)
                                    .distinct()
                                    .map(cu -> rxJoin(cu, acl))
                                    .collect(Collectors.toList());
                    if (joins.isEmpty()) {
                        throw new NoSuchElementException("UserSyncgroup requires a username; no " +
                                "username blessings found. Blessings: " + b);
                    }
                    return Observable.merge(joins);
                }));
    }
}
