// 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.debug;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

import org.apache.commons.io.FileUtils;
import org.joda.time.Duration;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import io.v.android.v23.V;
import io.v.baku.toolkit.blessings.BlessingsUtils;
import io.v.impl.google.services.syncbase.SyncbaseServer;
import io.v.rx.VFn;
import io.v.v23.context.VContext;
import io.v.v23.rpc.Server;
import io.v.v23.verror.VException;
import lombok.Value;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import rx.Observable;
import rx.Subscription;
import rx.schedulers.Schedulers;
import rx.util.async.Async;

/**
 * Syncbase Android service in lieu of GMS Core Syncbase. Exposes Syncbase as a simplistic bound
 * service, relying on Vanadium RPC in lieu of IPC, with open permissions, returning the local
 * Vanadium name in {@link Binder#getObservable()}...{@link BindResult#getName()}.
 */
@Slf4j
public class SyncbaseAndroidService extends Service {
    public static final String
            EXTRA_CLEAN_START = "EXTRA_CLEAN_START",
            EXTRA_KEEP_ALIVE = "EXTRA_KEEP_ALIVE";

    public static final Duration DEFAULT_KEEP_ALIVE = Duration.standardMinutes(5);
    private static final Duration STOP_TIMEOUT = Duration.standardSeconds(5);

    @Accessors(prefix = "m")
    @Value
    public static class BindResult {
        Server mServer;
        String mName;
    }

    private VContext mVContext;
    private Observable<BindResult> mObservable;
    private Subscription mKill;
    private Duration mKeepAlive;

    public class Binder extends android.os.Binder {
        private Binder() {
        }

        public Observable<BindResult> getObservable() {
            return mObservable;
        }
    }

    @Override
    public void onCreate() {
        mVContext = V.init(this);
        // If we don't proxy, it seems we can't even mount.
        try {
            mVContext = V.withListenSpec(mVContext, V.getListenSpec(mVContext).withProxy("proxy"));
        } catch (final VException e) {
            log.warn("Unable to set up Vanadium proxy for Syncbase", e);
        }
    }

    @Override
    public void onDestroy() {
        try {
            mObservable.doOnNext(VFn.unchecked(b -> {
                log.info("Stopping Syncbase");
                mVContext.cancel();
            }))
                    .timeout(STOP_TIMEOUT.getMillis(), TimeUnit.MILLISECONDS)
                    .toBlocking()
                    .single();
            log.info("Syncbase is over");
            // TODO(rosswang): https://github.com/vanadium/issues/issues/809
            System.exit(0);
        } catch (final RuntimeException e) {
            log.error("Failed to shut down Syncbase", e);
            System.exit(1);
        }
    }

    @Override
    public int onStartCommand(final Intent intent, final int flags, final int startId) {
        ensureStarted(intent);
        return START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(final Intent intent) {
        ensureStarted(intent);
        return new Binder();
    }

    @Override
    public boolean onUnbind(final Intent intent) {
        mKill = Observable.timer(mKeepAlive.getMillis(), TimeUnit.MILLISECONDS)
                .subscribe(x -> stopSelf());
        return true;
    }

    @Override
    public void onRebind(final Intent intent) {
        mKill.unsubscribe();
    }

    private void ensureStarted(final Intent intent) {
        if (mObservable == null) {
            mObservable = Async.fromCallable(() -> startServer(intent), Schedulers.io())
                    .replay(1).autoConnect(0); //cache last result; connect immediately
        }
    }

    private BindResult startServer(final Intent intent) throws SyncbaseServer.StartException {
        final File storageRoot = new File(getFilesDir(), "syncbase");

        mKeepAlive = (Duration)intent.getSerializableExtra(EXTRA_KEEP_ALIVE);
        if (mKeepAlive == null) {
            mKeepAlive = DEFAULT_KEEP_ALIVE;
        }

        if (intent.getBooleanExtra(EXTRA_CLEAN_START, false)) {
            log.info("Clearing Syncbase data per intent");
            try {
                FileUtils.deleteDirectory(storageRoot);
            } catch (final IOException e) {
                log.error("Could not clear Syncbase data", e);
            }
        }

        storageRoot.mkdirs();

        log.info("Starting Syncbase");
        final VContext sbCtx = SyncbaseServer.withNewServer(mVContext, new SyncbaseServer.Params()
                .withPermissions(BlessingsUtils.OPEN_DATA_PERMS)
                .withStorageRootDir(storageRoot.getAbsolutePath()));
        final Server server = V.getServer(sbCtx);
        return new BindResult(server, "/" + server.getStatus().getEndpoints()[0]);
    }
}
