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

import 'dart:async';
import 'dart:io';

import 'package:logging/logging.dart';
import 'package:path/path.dart' as pathutil;

import '../models/all.dart' as model;
import '../stores/store.dart';
import '../stores/utils/key.dart' as keyutil;
import '../utils/uuid.dart' as uuidutil;

final Logger log = new Logger('loader');

const String _baseDecksPath = '/sdcard/syncslides/decks';
Directory _baseDecksDir = new Directory(_baseDecksPath);

// Loader is responsible for importing existing decks and slides into the store.
class Loader {
  final Store _store = new Store.singleton();
  static Loader _singletonLoader = new Loader._internal();

  factory Loader.singleton() {
    return _singletonLoader;
  }

  Loader._internal() {}

  // Loads all the decks in /sdcard/syncslides/decks
  // Name of each deck is the name of its directory.
  // Slide image files must be numbered.
  // First slide is used as the thumbnail.
  // Example:
  // /sdcard/syncslides/decks/Foo
  //    /sdcard/syncslides/decks/Foo/1.png
  //    /sdcard/syncslides/decks/Foo/2.png
  // /sdcard/syncslides/decks/Bar
  //    /sdcard/syncslides/decks/Bar/1.gif
  //
  // TODO(aghassemi): Replace with a Path Selector dialog.
  Future loadDeck() async {
    if (!await _baseDecksDir.exists()) {
      log.warning('Default $_baseDecksPath directory does not exist.');
      return;
    }

    Stream allDecksDir = _baseDecksDir.list();
    await for (FileSystemEntity fsEntity in allDecksDir) {
      if (!(fsEntity is Directory)) {
        log.warning(
            'Ignoring non-directory ${pathutil.basename(fsEntity.path)} in $_baseDecksPath');
        continue;
      }
      _loadDeck(fsEntity.path);
    }
  }

  Future _loadDeck(String path) async {
    var deckName = pathutil.basename(path);
    var deckId = uuidutil.createUuid();

    Directory deckDir = new Directory(path);
    List<model.Slide> slides = new List();
    await for (FileSystemEntity fsEntity in deckDir.list()) {
      if (!(fsEntity is File)) {
        log.warning(
            'Ignoring non-file ${pathutil.basename(fsEntity.path)} in $path');
        continue;
      }
      File slideFile = fsEntity as File;
      var slideNum;
      try {
        String slideName = pathutil.basenameWithoutExtension(slideFile.path);
        slideNum = int.parse(slideName);
        slideNum--; // Zero based index.
      } catch (e) {
        throw new ArgumentError(
            "Filename ${pathutil.basename(slideFile.path)} for a slide must be a number.");
      }

      // Create the slide object.
      List<int> slideBytes = await slideFile.readAsBytes();
      var blobRef = new model.BlobRef(
          keyutil.getDeckBlobKey(deckId, uuidutil.createUuid()));
      await _store.actions.putBlob(blobRef.key, slideBytes);
      model.Slide slide = new model.Slide(slideNum, blobRef);
      slides.add(slide);
    }

    if (slides.isEmpty) {
      log.warning('No image files found in $path.');
      return;
    }

    slides.sort((model.Slide s1, model.Slide s2) => s1.num.compareTo(s2.num));

    // Use the first slide as thumbnail.
    model.BlobRef thumbnailBlobRef = slides.first.image;
    var deck = new model.Deck(deckId, deckName, thumbnailBlobRef);

    await _store.actions.addDeck(deck);
    await _store.actions.setSlides(deck.key, slides);
  }
}
