// Copyright 2016 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.baku.examples.distro;

import android.app.Service;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.IBinder;
import android.provider.ContactsContract;
import android.support.annotation.Nullable;
import android.util.Log;

import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.SettableFuture;
import com.jaredrummler.android.device.DeviceName;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import io.v.android.v23.V;
import io.v.v23.context.VContext;
import io.v.v23.rpc.Server;
import io.v.v23.rpc.ServerCall;
import io.v.v23.security.BlessingPattern;
import io.v.v23.security.Blessings;
import io.v.v23.security.VPrincipal;
import io.v.v23.security.VSecurity;
import io.v.v23.vdl.ServerRecvStream;
import io.v.v23.verror.VException;
import io.v.v23.vom.VomUtil;
import lombok.RequiredArgsConstructor;

public class DistroAndroidService extends Service {
    private static final String TAG = DistroAndroidService.class.getSimpleName();

    @RequiredArgsConstructor
    public static class Session {
        public final SettableFuture<Void> completion;
        public final ServerRecvStream<State> stream;
    }

    private static Map<String, Session> sessions = new HashMap<>();

    public static Session getSession(final String key) {
        return sessions.get(key);
    }

    public static final String
            BLESSINGS_EXTRA = "Blessings";

    private VContext vContext;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        vContext = V.init(this);

        final VPrincipal principal = V.getPrincipal(vContext);

        final Blessings blessings;
        try {
            blessings = (Blessings) VomUtil.decodeFromString(
                    intent.getStringExtra(BLESSINGS_EXTRA), Blessings.class);

            principal.blessingStore().setDefaultBlessings(blessings);
            principal.blessingStore().set(blessings, new BlessingPattern("..."));
            VSecurity.addToRoots(principal, blessings);
        } catch (final VException e) {
            // TODO(rosswang): handle this better
            Log.e(TAG, "Unable to assume blessings", e);
        }

        final DistroServer handlers = new DistroServer() {
            @Override
            public ListenableFuture<String> getDescription(final VContext context,
                                                           final ServerCall call) {
                final SettableFuture<String> description = SettableFuture.create();

                DeviceName.with(DistroAndroidService.this).request((i, e) -> {
                    final String owner;

                    final ContentResolver cr = getContentResolver();
                    try (final Cursor c = cr.query(Uri.withAppendedPath(
                            ContactsContract.Profile.CONTENT_URI,
                            ContactsContract.Contacts.Data.CONTENT_DIRECTORY),
                            null, null, null, null)) {

                        if (c.getCount() > 0) {
                            c.moveToFirst();
                            owner = c.getString(c.getColumnIndex(
                                    ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME)) +
                                    "'s ";
                        } else {
                            owner = "";
                        }
                    }

                    final String device = e == null ? i.getName() : DeviceName.getDeviceName();
                    description.set(owner + device);
                });

                return description;
            }

            @Override
            public ListenableFuture<Void> cast(final VContext context, final ServerCall call,
                                               final ServerRecvStream<State> stream) {
                final String key = UUID.randomUUID().toString();
                final SettableFuture<Void> completion = SettableFuture.create();
                completion.addListener(() -> sessions.remove(key), MoreExecutors.directExecutor());

                sessions.put(key, new Session(completion, stream));

                final Intent intent = new Intent(DistroAndroidService.this, HostActivity.class);
                intent.putExtra(HostActivity.SESSION_EXTRA, key);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                try {
                    startActivity(intent);
                } catch (final Exception e) {
                    completion.setException(e);
                    Log.e(TAG, e.getMessage(), e);
                }

                return completion;
            }
        };

        VContext listenContextCandidate;
        try {
            listenContextCandidate = V.withListenSpec(vContext,
                    V.getListenSpec(vContext).withProxy("proxy"));
        } catch (final VException e) {
            listenContextCandidate = vContext;
            Log.e(TAG, "Unable to listen on proxy", e);
        }

        final VContext listenContext = listenContextCandidate;

        final Server s;
        try {
            s = V.getServer(V.withNewServer(listenContext, Disco.name(this), handlers,
                    VSecurity.newAllowEveryoneAuthorizer()));
        } catch (final VException e) {
            throw new RuntimeException(e);
        }

        return START_REDELIVER_INTENT;
    }

    @Override
    public void onDestroy() {
        vContext.cancel();
    }
}
