package jp.sourceforge.nicoro;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;

import java.lang.ref.WeakReference;

import static jp.sourceforge.nicoro.Log.LOG_TAG;

/**
 * 本体クラスへの参照を{@link WeakReference}で持つ{@link ServiceConnection}
 * @param <T> 本体クラス
 */
public abstract class ServiceConnectionWrapper<T> implements ServiceConnection {
    private static final boolean DEBUG_LOGD = Release.IS_DEBUG & true;

    private WeakReference<T> mRef;
    private boolean mBound = false;

    protected ServiceConnectionWrapper(T ref) {
        mRef = new WeakReference<T>(ref);
    }

    public T getBody() {
        return mRef.get();
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        if (DEBUG_LOGD) {
            Log.d(LOG_TAG, Log.buf().append(getClass().getSimpleName())
                    .append("#onServiceConnected")
                    .append(name.toString()).append(' ')
                    .append(service.toString()).toString());
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        if (DEBUG_LOGD) {
            Log.d(LOG_TAG, Log.buf().append(getClass().getSimpleName())
                    .append("#onServiceDisconnected")
                    .append(name.toString()).toString());
        }
    }

    /**
     * @see Context#bindService
     * @param context
     * @param intent
     * @param flags
     * @return
     */
    public boolean bindService(Context context, Intent intent, int flags) {
        boolean ret = context.bindService(intent, this, flags);
        mBound = ret;
        return ret;
    }

    /**
     * @see Context#bindService
     * @param context
     */
    public void unbindService(Context context) {
        if (mBound) {
            try {
                context.unbindService(this);
            } catch (IllegalArgumentException e) {
                // XXX 非bind状態で呼ばれるケースがあるようなのでcatch
                Log.e(LOG_TAG, e.toString(), e);
            }
            mBound = false;
        }
    }
}
