// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. 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 'logger.dart';

typedef Future<String> FetchDataFunction();
typedef Future<String> WithCacheFunction(FetchDataFunction fetchData,
    [String key]);
typedef WithCacheFunction CreateCacheFunction(
    {String overrideKey, Duration duration});

CreateCacheFunction initCache(Uri baseUri, [Logger logger]) {
  final cache = new Cache(baseUri, logger);
  logger ??= new StdOutLogger(Level.warning);

  return ({String overrideKey, Duration duration}) {
    if (duration == null) {
      duration = new Duration(hours: 24);
    }

    return (FetchDataFunction call, [String key]) async {
      if (overrideKey != null) {
        key = overrideKey;
      }
      if (key == null || key.isEmpty) {
        logger.warning("Key is null or empty - cannot cache result");
        return null;
      }
      // format key
      key = key
          .replaceAll("/", "_")
          .replaceAll(":", "")
          .replaceAll(".", "_")
          .replaceAll("?", "")
          .replaceAll("%2F", "_")
          .replaceAll("*", "x");

      var cacheResult = await cache.read(key, duration);
      if (cacheResult.hasResult) {
        logger.debug("Found key $key in cache");
        return cacheResult.result;
      }

      logger.debug("Could not find key $key in cache");

      // we have to make a call
      String result = await call();

      // insert/update the cache
      if (key != null && !key.isEmpty) {
        await cache.write(key, result);
      }

      return result;
    };
  };
}

CreateCacheFunction noCache() {
  return ({String overrideKey, Duration duration}) {
    return (FetchDataFunction fetchData, [String key]) {
      return fetchData();
    };
  };
}

/// Simple cache for caching data.
class Cache {
  // TODO(mkroghj) use this instead of cache.dart
  Uri base;
  Logger logger;

  Cache(this.base, this.logger);

  Map<String, String> memoryCache = <String, String>{};

  /// Checks if key [path] is in cache
  Future<bool> containsKey(String path, [Duration duration]) async {
    if (memoryCache.containsKey(path)) return true;

    File file = new File.fromUri(base.resolve(path));
    if (await file.exists()) {
      return duration == null
          ? true
          : new DateTime.now().difference(await file.lastModified()) <=
              duration;
    }

    return false;
  }

  /// Try reading [path] from cache
  Future<CacheResult> read(String path, [Duration duration]) async {
    if (memoryCache.containsKey(path)) {
      logger.debug('Found $path in memory cache');
      return new CacheResult(memoryCache[path]);
    }

    File file = new File.fromUri(base.resolve(path));

    if (!await file.exists()) {
      logger.debug('Could not find file $path in file cache');
      return new CacheResult.noResult();
    }
    if (duration != null &&
        new DateTime.now().difference(await file.lastModified()) > duration) {
      logger.debug('File $path was found but the information is too stale,'
          'for the duration: $duration');
      return new CacheResult.noResult();
    }

    logger.debug('Found $path in file cache');
    try {
      String text = await file.readAsString();
      memoryCache[path] = text;
      return new CacheResult(text);
    } catch (error, st) {
      logger.error("Could not read $path:", error, st);
      return new CacheResult.noResult();
    }
  }

  /// Store [text] as the cache data for [path].
  Future write(String path, String text) async {
    logger.debug('Creating $path in file cache');
    File file = new File.fromUri(base.resolve(path));
    if (!await file.exists()) {
      await file.create(recursive: true);
    }
    await file.writeAsString(text);
    memoryCache[path] = text;
  }

  /// Clears the cache at [baseUri]
  Future clearCache(Uri baseUri) async {
    await new Directory(baseUri.toFilePath()).delete(recursive: true);
  }
}

class CacheResult {
  final bool hasResult;
  final String result;

  CacheResult.noResult()
      : hasResult = false,
        result = null {}

  CacheResult(this.result) : hasResult = true {}
}
