/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.notification;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.provider.CalendarContract.Attendees;
import android.provider.CalendarContract.Calendars;
import android.provider.CalendarContract.Events;
import android.provider.CalendarContract.Instances;
import android.service.notification.ZenModeConfig.EventInfo;
import android.util.ArraySet;
import android.util.Log;

import java.io.PrintWriter;
import java.util.Date;
import java.util.Objects;

public class CalendarTracker {
    private static final String TAG = "ConditionProviders.CT";
    private static final boolean DEBUG = Log.isLoggable("ConditionProviders", Log.DEBUG);
    private static final boolean DEBUG_ATTENDEES = false;

    private static final int EVENT_CHECK_LOOKAHEAD = 24 * 60 * 60 * 1000;

    private static final String[] INSTANCE_PROJECTION = {
            Instances.BEGIN,
            Instances.END,
            Instances.TITLE,
            Instances.VISIBLE,
            Instances.EVENT_ID,
            Instances.CALENDAR_DISPLAY_NAME,
            Instances.OWNER_ACCOUNT,
            Instances.CALENDAR_ID,
            Instances.AVAILABILITY,
    };

    private static final String INSTANCE_ORDER_BY = Instances.BEGIN + " ASC";

    private static final String[] ATTENDEE_PROJECTION = {
        Attendees.EVENT_ID,
        Attendees.ATTENDEE_EMAIL,
        Attendees.ATTENDEE_STATUS,
    };

    private static final String ATTENDEE_SELECTION = Attendees.EVENT_ID + " = ? AND "
            + Attendees.ATTENDEE_EMAIL + " = ?";

    private final Context mSystemContext;
    private final Context mUserContext;

    private Callback mCallback;
    private boolean mRegistered;

    public CalendarTracker(Context systemContext, Context userContext) {
        mSystemContext = systemContext;
        mUserContext = userContext;
    }

    public void setCallback(Callback callback) {
        if (mCallback == callback) return;
        mCallback = callback;
        setRegistered(mCallback != null);
    }

    public void dump(String prefix, PrintWriter pw) {
        pw.print(prefix); pw.print("mCallback="); pw.println(mCallback);
        pw.print(prefix); pw.print("mRegistered="); pw.println(mRegistered);
        pw.print(prefix); pw.print("u="); pw.println(mUserContext.getUserId());
    }

    private ArraySet<Long> getPrimaryCalendars() {
        final long start = System.currentTimeMillis();
        final ArraySet<Long> rt = new ArraySet<>();
        final String primary = "\"primary\"";
        final String[] projection = { Calendars._ID,
                "(" + Calendars.ACCOUNT_NAME + "=" + Calendars.OWNER_ACCOUNT + ") AS " + primary };
        final String selection = primary + " = 1";
        Cursor cursor = null;
        try {
            cursor = mUserContext.getContentResolver().query(Calendars.CONTENT_URI, projection,
                    selection, null, null);
            while (cursor != null && cursor.moveToNext()) {
                rt.add(cursor.getLong(0));
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        if (DEBUG) Log.d(TAG, "getPrimaryCalendars took " + (System.currentTimeMillis() - start));
        return rt;
    }

    public CheckEventResult checkEvent(EventInfo filter, long time) {
        final Uri.Builder uriBuilder = Instances.CONTENT_URI.buildUpon();
        ContentUris.appendId(uriBuilder, time);
        ContentUris.appendId(uriBuilder, time + EVENT_CHECK_LOOKAHEAD);
        final Uri uri = uriBuilder.build();
        final Cursor cursor = mUserContext.getContentResolver().query(uri, INSTANCE_PROJECTION,
                null, null, INSTANCE_ORDER_BY);
        final CheckEventResult result = new CheckEventResult();
        result.recheckAt = time + EVENT_CHECK_LOOKAHEAD;
        try {
            final ArraySet<Long> primaryCalendars = getPrimaryCalendars();
            while (cursor != null && cursor.moveToNext()) {
                final long begin = cursor.getLong(0);
                final long end = cursor.getLong(1);
                final String title = cursor.getString(2);
                final boolean calendarVisible = cursor.getInt(3) == 1;
                final int eventId = cursor.getInt(4);
                final String name = cursor.getString(5);
                final String owner = cursor.getString(6);
                final long calendarId = cursor.getLong(7);
                final int availability = cursor.getInt(8);
                final boolean calendarPrimary = primaryCalendars.contains(calendarId);
                if (DEBUG) Log.d(TAG, String.format(
                        "%s %s-%s v=%s a=%s eid=%s n=%s o=%s cid=%s p=%s",
                        title,
                        new Date(begin), new Date(end), calendarVisible,
                        availabilityToString(availability), eventId, name, owner, calendarId,
                        calendarPrimary));
                final boolean meetsTime = time >= begin && time < end;
                final boolean meetsCalendar = calendarVisible && calendarPrimary
                        && (filter.calendar == null || Objects.equals(filter.calendar, owner)
                        || Objects.equals(filter.calendar, name));
                final boolean meetsAvailability = availability != Instances.AVAILABILITY_FREE;
                if (meetsCalendar && meetsAvailability) {
                    if (DEBUG) Log.d(TAG, "  MEETS CALENDAR & AVAILABILITY");
                    final boolean meetsAttendee = meetsAttendee(filter, eventId, owner);
                    if (meetsAttendee) {
                        if (DEBUG) Log.d(TAG, "    MEETS ATTENDEE");
                        if (meetsTime) {
                            if (DEBUG) Log.d(TAG, "      MEETS TIME");
                            result.inEvent = true;
                        }
                        if (begin > time && begin < result.recheckAt) {
                            result.recheckAt = begin;
                        } else if (end > time && end < result.recheckAt) {
                            result.recheckAt = end;
                        }
                    }
                }
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return result;
    }

    private boolean meetsAttendee(EventInfo filter, int eventId, String email) {
        final long start = System.currentTimeMillis();
        String selection = ATTENDEE_SELECTION;
        String[] selectionArgs = { Integer.toString(eventId), email };
        if (DEBUG_ATTENDEES) {
            selection = null;
            selectionArgs = null;
        }
        final Cursor cursor = mUserContext.getContentResolver().query(Attendees.CONTENT_URI,
                ATTENDEE_PROJECTION, selection, selectionArgs, null);
        try {
            if (cursor == null || cursor.getCount() == 0) {
                if (DEBUG) Log.d(TAG, "No attendees found");
                return true;
            }
            boolean rt = false;
            while (cursor != null && cursor.moveToNext()) {
                final long rowEventId = cursor.getLong(0);
                final String rowEmail = cursor.getString(1);
                final int status = cursor.getInt(2);
                final boolean meetsReply = meetsReply(filter.reply, status);
                if (DEBUG) Log.d(TAG, (DEBUG_ATTENDEES ? String.format(
                        "rowEventId=%s, rowEmail=%s, ", rowEventId, rowEmail) : "") +
                        String.format("status=%s, meetsReply=%s",
                        attendeeStatusToString(status), meetsReply));
                final boolean eventMeets = rowEventId == eventId && Objects.equals(rowEmail, email)
                        && meetsReply;
                rt |= eventMeets;
            }
            return rt;
        } finally {
            if (cursor != null) {
                cursor.close();
            }
            if (DEBUG) Log.d(TAG, "meetsAttendee took " + (System.currentTimeMillis() - start));
        }
    }

    private void setRegistered(boolean registered) {
        if (mRegistered == registered) return;
        final ContentResolver cr = mSystemContext.getContentResolver();
        final int userId = mUserContext.getUserId();
        if (mRegistered) {
            if (DEBUG) Log.d(TAG, "unregister content observer u=" + userId);
            cr.unregisterContentObserver(mObserver);
        }
        mRegistered = registered;
        if (DEBUG) Log.d(TAG, "mRegistered = " + registered + " u=" + userId);
        if (mRegistered) {
            if (DEBUG) Log.d(TAG, "register content observer u=" + userId);
            cr.registerContentObserver(Instances.CONTENT_URI, true, mObserver, userId);
            cr.registerContentObserver(Events.CONTENT_URI, true, mObserver, userId);
            cr.registerContentObserver(Calendars.CONTENT_URI, true, mObserver, userId);
        }
    }

    private static String attendeeStatusToString(int status) {
        switch (status) {
            case Attendees.ATTENDEE_STATUS_NONE: return "ATTENDEE_STATUS_NONE";
            case Attendees.ATTENDEE_STATUS_ACCEPTED: return "ATTENDEE_STATUS_ACCEPTED";
            case Attendees.ATTENDEE_STATUS_DECLINED: return "ATTENDEE_STATUS_DECLINED";
            case Attendees.ATTENDEE_STATUS_INVITED: return "ATTENDEE_STATUS_INVITED";
            case Attendees.ATTENDEE_STATUS_TENTATIVE: return "ATTENDEE_STATUS_TENTATIVE";
            default: return "ATTENDEE_STATUS_UNKNOWN_" + status;
        }
    }

    private static String availabilityToString(int availability) {
        switch (availability) {
            case Instances.AVAILABILITY_BUSY: return "AVAILABILITY_BUSY";
            case Instances.AVAILABILITY_FREE: return "AVAILABILITY_FREE";
            case Instances.AVAILABILITY_TENTATIVE: return "AVAILABILITY_TENTATIVE";
            default: return "AVAILABILITY_UNKNOWN_" + availability;
        }
    }

    private static boolean meetsReply(int reply, int attendeeStatus) {
        switch (reply) {
            case EventInfo.REPLY_YES:
                return attendeeStatus == Attendees.ATTENDEE_STATUS_ACCEPTED;
            case EventInfo.REPLY_YES_OR_MAYBE:
                return attendeeStatus == Attendees.ATTENDEE_STATUS_ACCEPTED
                        || attendeeStatus == Attendees.ATTENDEE_STATUS_TENTATIVE;
            case EventInfo.REPLY_ANY_EXCEPT_NO:
                return attendeeStatus != Attendees.ATTENDEE_STATUS_DECLINED;
            default:
                return false;
        }
    }

    private final ContentObserver mObserver = new ContentObserver(null) {
        @Override
        public void onChange(boolean selfChange, Uri u) {
            if (DEBUG) Log.d(TAG, "onChange selfChange=" + selfChange + " uri=" + u
                    + " u=" + mUserContext.getUserId());
            mCallback.onChanged();
        }

        @Override
        public void onChange(boolean selfChange) {
            if (DEBUG) Log.d(TAG, "onChange selfChange=" + selfChange);
        }
    };

    public static class CheckEventResult {
        public boolean inEvent;
        public long recheckAt;
    }

    public interface Callback {
        void onChanged();
    }

}
