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

// Copyright 2016 The Chromium 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.Activity;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.os.Bundle;
import android.util.Log;

import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;

import org.chromium.base.PathUtils;
import org.joda.time.Duration;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import io.flutter.view.FlutterMain;
import io.flutter.view.FlutterView;
import io.v.android.VAndroidContext;
import io.v.android.VAndroidContexts;
import io.v.android.security.BlessingsManager;
import io.v.v23.security.Blessings;
import io.v.v23.vdl.ClientSendStream;
import io.v.v23.verror.VException;
import io.v.v23.vom.VomUtil;
import java8.util.Maps;
import lombok.RequiredArgsConstructor;
import rx.Subscription;

/**
 * Activity representing the example 'app', a.k.a. the initiator/originator/master.
 */
public class DistroActivity extends Activity {
    private static final String TAG = DistroActivity.class.getSimpleName();
    private static final Duration PING_TIMEOUT = Duration.standardSeconds(2);
    private static final long POLL_INTERVAL = 750;

    private VAndroidContext context;
    private FlutterView flutterView;
    private final Map<String, ConnectionMonitor> clients = new HashMap<>();
    private ScheduledExecutorService poller;
    private Subscription subscription;

    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        poller = new ScheduledThreadPoolExecutor(1);

        FlutterMain.ensureInitializationComplete(getApplicationContext(), null);
        setContentView(R.layout.flutter_layout);

        flutterView = (FlutterView) findViewById(R.id.flutter_view);
        File appBundle = new File(PathUtils.getDataDirectory(this),
                FlutterMain.APP_BUNDLE);
        flutterView.runFromBundle(appBundle.getPath(), null);

        flutterView.sendToFlutter("runApp", "", r -> {
            context = VAndroidContexts.withDefaults(this, savedInstanceState);

            Futures.addCallback(BlessingsManager
                            .getBlessings(context.getVContext(), this, "blessings", true),
                    new FutureCallback<Blessings>() {
                        @Override
                        public void onSuccess(final Blessings blessings) {
                            onBlessingsAvailable(blessings);
                        }

                        @Override
                        public void onFailure(final Throwable t) {
                            Log.e(TAG, "Unable to attain blessings", t);
                        }
                    });
        });
    }

    private void onBlessingsAvailable(final Blessings blessings) {
        final Intent castIntent = new Intent(DistroActivity.this,
                DistroAndroidService.class);
        try {
            castIntent.putExtra(DistroAndroidService.BLESSINGS_EXTRA,
                    VomUtil.encodeToString(blessings, Blessings.class));
        } catch (final VException e) {
            Log.e(TAG, "Unable to encode blessings", e);
        }
        startService(castIntent);

        subscription = startScanning();

        flutterView.addOnMessageListener("initiateCast", this::initiateCast);
        flutterView.addOnMessageListener("updateCast", this::updateCast);
        flutterView.addOnMessageListener("terminateCast", this::terminateCast);
    }

    @Override
    protected void onDestroy() {
        if (subscription != null) {
            subscription.unsubscribe();
        }

        poller.shutdown();
        clients.clear();

        if (flutterView != null) {
            flutterView.destroy();
        }

        context.close();

        super.onDestroy();
    }

    @Override
    protected void onPause() {
        super.onPause();
        flutterView.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        flutterView.onResume();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        // Reload the Flutter Dart code when the activity receives an intent
        // from the "flutter refresh" command.
        // This feature should only be enabled during development.  Use the
        // debuggable flag as an indicator that we are in development mode.
        if ((getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
            if (Intent.ACTION_RUN.equals(intent.getAction())) {
                flutterView.runFromBundle(intent.getDataString(),
                        intent.getStringExtra("snapshot"));
            }
        }
    }

    private boolean isActive() {
        return subscription != null && !subscription.isUnsubscribed();
    }

    private class ConnectionMonitor implements FutureCallback<String> {
        final String name;

        private final DistroClient client;

        private ClientSendStream<State, Void> castStream;

        private ListenableFuture<String> poll;

        private final FutureCallback<Object> failureHandler = new FutureCallback<Object>() {
            @Override
            public void onSuccess(final Object result) {
            }

            @Override
            public void onFailure(final Throwable t) {
                if (isActive()) {
                    flutterView.sendToFlutter("deviceOffline", name);
                    terminateCast();
                    clients.remove(name);
                }
            }
        };

        public ConnectionMonitor(final String name) {
            this.name = name;
            client = DistroClientFactory.getDistroClient(name);

            poll();
        }

        public void poll() {
            poll = client.getDescription(context.getVContext().withTimeout(PING_TIMEOUT));
            Futures.addCallback(poll, this);
        }

        @Override
        public void onSuccess(final String description) {
            if (isActive()) {
                final JSONObject message = new JSONObject();
                try {
                    message.put("name", name);
                    message.put("description", description);
                } catch (final JSONException wtf) {
                    throw new RuntimeException(wtf);
                }
                flutterView.sendToFlutter("deviceOnline", message.toString());

                poller.schedule(this::poll, POLL_INTERVAL, TimeUnit.MILLISECONDS);
            }
        }

        @Override
        public void onFailure(final Throwable t) {
            failureHandler.onFailure(t);
        }

        public ConnectionMonitor initiateCast() {
            castStream = client.cast(context.getVContext());
            return this;
        }

        public void updateCast(final String data) {
            Futures.addCallback(castStream.send(new State(data)), failureHandler);
        }

        public void terminateCast() {
            if (castStream != null) {
                Futures.addCallback(castStream.finish(), failureHandler);
                castStream = null;
            }
        }
    }

    private Subscription startScanning() {
        return Disco.scanContinuously(context)
                .subscribe(name -> Maps.computeIfAbsent(clients, name, ConnectionMonitor::new),
                        t -> context.getErrorReporter().onError(R.string.err_scan, t));
    }

    @RequiredArgsConstructor
    private static class CastMessage {
        public final String name, data;

        public static CastMessage fromJson(final String json) {
            final JSONObject message;
            try {
                message = new JSONObject(json);
                return new CastMessage(
                        message.getString("name"),
                        message.getString("data"));
            } catch (final JSONException e) {
                throw new IllegalArgumentException(e);
            }
        }
    }

    private String initiateCast(final String json) {
        final CastMessage message = CastMessage.fromJson(json);
        clients.get(message.name)
                .initiateCast()
                .updateCast(message.data);
        return null;
    }

    private String updateCast(final String json) {
        final CastMessage message = CastMessage.fromJson(json);
        clients.get(message.name)
                .updateCast(message.data);
        return null;
    }

    private String terminateCast(final String name) {
        final ConnectionMonitor conn = clients.get(name);
        if (conn != null) {
            conn.terminateCast();
        }

        return null;
    }
}
