<commit_before>package com.seatgeek.placesautocomplete.history;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.util.AtomicFile;
import android.text.TextUtils;
import android.util.Log;

import com.seatgeek.placesautocomplete.Constants;
import com.seatgeek.placesautocomplete.PlacesAutocompleteTextView;
import com.seatgeek.placesautocomplete.async.BackgroundExecutorService;
import com.seatgeek.placesautocomplete.async.BackgroundJob;
import com.seatgeek.placesautocomplete.json.JsonParserResolver;
import com.seatgeek.placesautocomplete.json.PlacesApiJsonParser;
import com.seatgeek.placesautocomplete.model.Place;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class DefaultAutocompleteHistoryManager implements AutocompleteHistoryManager {
    private static final String BASE_AUTOCOMPLETE_HISTORY_DIR = "autocomplete/";
    private static final int MAX_HISTORY_ITEM_COUNT = 5;

    public static AutocompleteHistoryManager fromPath(@NonNull Context context, @NonNull String historyFileName) {
        if (TextUtils.isEmpty(historyFileName)) {
            throw new IllegalArgumentException("Cannot have an empty historyFile name");
        }

        File historyFile = new File(context.getCacheDir(), BASE_AUTOCOMPLETE_HISTORY_DIR + historyFileName);

        return new DefaultAutocompleteHistoryManager(historyFile, JsonParserResolver.JSON_PARSER);
    }

    @NonNull
    private final AtomicFile savedFile;

    @NonNull
    private final PlacesApiJsonParser jsonParser;

    @NonNull
    private List<Place> places;

    @Nullable
    private OnHistoryUpdatedListener listener;

    private DefaultAutocompleteHistoryManager(@NonNull final File historyFile, @NonNull final PlacesApiJsonParser parser) {
        savedFile = new AtomicFile(historyFile);

        jsonParser = parser;

        places = new ArrayList<>();

        readPlaces();
    }

    private void readPlaces() {
        BackgroundExecutorService.INSTANCE.enqueue(new BackgroundJob<List<Place>>() {
            @Override
            public List<Place> executeInBackground() throws Exception {
                if (!savedFile.getBaseFile().exists()) {
                    throw new FileNotFoundException("History file does not exist");
                }

                InputStream is = null;
                try {
                    is = savedFile.openRead();
                    return jsonParser.readHistoryJson(is);
                } finally {
                    if (is != null) {
                        is.close();
                    }
                }
            }

            @Override
            public void onSuccess(final List<Place> result) {
                Collections.reverse(result);

                for (Place place : result) {
                    internalAddItem(place);
                }
            }

            @Override
            public void onFailure(final Throwable error) {<commit_msg>Ensure we're creating proper dirs for history file. Return collections.emptyList() instead of throwing FNF since that's the expected behavior. Closes #14<commit_after>package com.seatgeek.placesautocomplete.history;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.util.AtomicFile;
import android.text.TextUtils;
import android.util.Log;

import com.seatgeek.placesautocomplete.Constants;
import com.seatgeek.placesautocomplete.PlacesAutocompleteTextView;
import com.seatgeek.placesautocomplete.async.BackgroundExecutorService;
import com.seatgeek.placesautocomplete.async.BackgroundJob;
import com.seatgeek.placesautocomplete.json.JsonParserResolver;
import com.seatgeek.placesautocomplete.json.PlacesApiJsonParser;
import com.seatgeek.placesautocomplete.model.Place;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class DefaultAutocompleteHistoryManager implements AutocompleteHistoryManager {
    private static final String BASE_AUTOCOMPLETE_HISTORY_DIR = "autocomplete/";
    private static final int MAX_HISTORY_ITEM_COUNT = 5;

    public static AutocompleteHistoryManager fromPath(@NonNull Context context, @NonNull String historyFileName) {
        if (TextUtils.isEmpty(historyFileName)) {
            throw new IllegalArgumentException("Cannot have an empty historyFile name");
        }


        File historyDir = new File(context.getCacheDir(), BASE_AUTOCOMPLETE_HISTORY_DIR);

        if (!historyDir.exists()) {
            historyDir.mkdirs();
        }

        return new DefaultAutocompleteHistoryManager(new File(historyDir, historyFileName), JsonParserResolver.JSON_PARSER);
    }

    @NonNull
    private final AtomicFile savedFile;

    @NonNull
    private final PlacesApiJsonParser jsonParser;

    @NonNull
    private List<Place> places;

    @Nullable
    private OnHistoryUpdatedListener listener;

    private DefaultAutocompleteHistoryManager(@NonNull final File historyFile, @NonNull final PlacesApiJsonParser parser) {
        savedFile = new AtomicFile(historyFile);

        jsonParser = parser;

        places = new ArrayList<>();

        readPlaces();
    }

    private void readPlaces() {
        BackgroundExecutorService.INSTANCE.enqueue(new BackgroundJob<List<Place>>() {
            @Override
            public List<Place> executeInBackground() throws Exception {
                if (!savedFile.getBaseFile().exists()) {
                    return Collections.emptyList();
                }

                InputStream is = null;
                try {
                    is = savedFile.openRead();
                    return jsonParser.readHistoryJson(is);
                } finally {
                    if (is != null) {
                        is.close();
                    }
                }
            }

            @Override
            public void onSuccess(final List<Place> result) {
                Collections.reverse(result);

                for (Place place : result) {
                    internalAddItem(place);
                }
            }

            @Override
            public void onFailure(final Throwable error) {
{'fraction_non_alphanumeric': 0.07714546561168593, 'fraction_numerical': 0.0009129640900791236, 'mean_word_length': 2.819291109819872, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3757118', 'n_tokens_mistral': 1718, 'n_tokens_neox': 1602, 'n_words': 373}