// 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.syncslides.lib;

import android.content.ContentResolver;
import android.support.v4.provider.DocumentFile;

import com.google.common.base.Charsets;
import com.google.common.io.ByteStreams;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;

import io.v.syncslides.db.DB;
import io.v.syncslides.model.Deck;
import io.v.syncslides.model.DeckImpl;
import io.v.syncslides.model.Slide;
import io.v.syncslides.model.SlideImpl;
import io.v.v23.verror.VException;

import static io.v.v23.VFutures.sync;

/**
 * Imports a slide deck from the given (local) folder directly into the DB.
 *
 * The folder must contain a JSON metadata file 'deck.json' with the following format:
 * {
 *     "Title" : "<title>",
 *     "Thumb" : "<filename>,
 *     "Slides" : [
 *          {
 *              "Thumb" : "<thumb_filename1>",
 *              "Image" : "<image_filename1>",
 *              "Note" : "<note1>"
 *          },
 *          {
 *              "Thumb" : "<thumb_filename2>",
 *              "Image" : "<image_filename2>",
 *              "Note" : "<note2>"
 *          },
 *
 *          ...
 *     ]
 * }
 *
 * All the filenames must be local to the given folder.
 */
public class DeckImporter {

    private static final String DECK_JSON = "deck.json";
    private static final String TITLE = "Title";
    private static final String THUMB = "Thumb";
    private static final String SLIDES = "Slides";
    private static final String IMAGE = "Image";
    private static final String NOTE = "Note";

    private final ListeningExecutorService mExecutorService;
    private ContentResolver mContentResolver;
    private DB mDB;

    public DeckImporter(ContentResolver contentResolver, DB db) {
        mExecutorService = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
        mContentResolver = contentResolver;
        mDB = db;
    }

    public ListenableFuture<Void> importDeck(final DocumentFile dir) {
        return mExecutorService.submit(() -> importDeckImpl(dir));
    }

    private Void importDeckImpl(DocumentFile dir) throws ImportException {
        if (!dir.isDirectory()) {
            throw new ImportException("Must import from a directory, got: " + dir);
        }
        // Read the deck metadata file.
        DocumentFile metadataFile = dir.findFile(DECK_JSON);
        if (metadataFile == null) {
            throw new ImportException("Couldn't find deck metadata file 'deck.json'");
        }
        JSONObject metadata = null;
        try {
            String data = new String(ByteStreams.toByteArray(
                    mContentResolver.openInputStream(metadataFile.getUri())),
                    Charsets.UTF_8);
            metadata = new JSONObject(data);
        } catch (FileNotFoundException e) {
            throw new ImportException("Couldn't open deck metadata file", e);
        } catch (IOException e) {
            throw new ImportException("Couldn't read data from deck metadata file", e);
        } catch (JSONException e) {
            throw new ImportException("Couldn't parse deck metadata", e);
        }

        try {
            String id = UUID.randomUUID().toString();
            String title = metadata.getString(TITLE);
            byte[] thumbData = readImage(dir, metadata.getString(THUMB));
            Deck deck = new DeckImpl(title, thumbData, id);
            Slide[] slides = readSlides(dir, metadata);
            sync(mDB.importDeck(deck, slides));
        } catch (JSONException e) {
            throw new ImportException("Invalid format for deck metadata", e);
        } catch (IOException e) {
            throw new ImportException("Error interpreting deck metadata", e);
        } catch (VException e) {
            throw new ImportException("Error importing deck", e);
        }
        return null;
    }

    // TODO(kash): Lazily read the slide images so we don't need to have them all
    // in memory simultaneously.
    private Slide[] readSlides(DocumentFile dir, JSONObject metadata)
            throws JSONException, IOException {
        if (!metadata.has(SLIDES)) {
            return new Slide[0];
        }
        JSONArray slides = metadata.getJSONArray(SLIDES);
        Slide[] ret = new Slide[slides.length()];
        for (int i = 0; i < slides.length(); ++i) {
            JSONObject slide = slides.getJSONObject(i);
            byte[] thumbData = readImage(dir, slide.getString(THUMB));
            byte[] imageData = thumbData;
            if (slide.has(IMAGE)) {
                imageData = readImage(dir, slide.getString(IMAGE));
            }
            String note = slide.getString(NOTE);
            // Temporarily use the thumbnail image's filename as the slide's unique ID.  SyncbaseDB
            // will generate a real ID on its own, so this is just a placeholder.
            ret[i] = new SlideImpl(slide.getString(THUMB), thumbData, imageData, note);
        }
        return ret;
    }

    private byte[] readImage(DocumentFile dir, String fileName) throws IOException {
        DocumentFile file = dir.findFile(fileName);
        if (file == null) {
            throw new FileNotFoundException("Image file doesn't exist: " + fileName);
        }
        return ByteStreams.toByteArray(mContentResolver.openInputStream(file.getUri()));
    }
}
