/*
 * The MIT License
 *
 * Copyright (c) 2016 Andreas Schattney
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package hochschuledarmstadt.photostream_tools;

import android.content.Context;
import android.util.Base64;

import com.google.gson.Gson;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import hochschuledarmstadt.photostream_tools.model.Photo;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class ImageCacherTest {

    public static final String CURRENT_DIR = new File(System.getProperty("user.dir")).getAbsolutePath();
    private Context context;
    private ImageCacher imageCacher;
    private File imageFile;

    private void educateMock(String fileName) {
        when(context.getFileStreamPath(fileName)).thenReturn(new File(CURRENT_DIR, fileName));
        try {
            when(context.openFileOutput(fileName, Context.MODE_PRIVATE)).thenReturn(new FileOutputStream(new File(CURRENT_DIR, fileName)));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    @Before
    public void setUp() {
        context = mock(Context.class);
        when(context.getFilesDir()).thenReturn(new File(CURRENT_DIR));
        imageCacher = new ImageCacher(context);
    }

    @After
    public void tearDown() {
        if (imageFile != null && imageFile.exists())
            imageFile.delete();
    }

    @Test
    public void isImageCached() {
        assertFalse(imageCacher.isCached(Integer.MAX_VALUE));
    }

    @Test
    public void cacheNewImage() {
        Photo photo = buildPhotoForImageCacher();
        try {
            assertTrue(imageCacher.cacheImage(photo));
            assertTrue(imageCacher.isCached(photo.getId()));
        } catch (IOException e) {
            e.printStackTrace();
            fail(e.toString());
        }
    }

    @Test
    public void detectImageAlreadyCached() {
        Photo photo = buildPhotoForImageCacher();
        try {
            assertTrue(imageCacher.cacheImage(photo));
            assertTrue(imageCacher.cacheImage(photo));
        } catch (IOException e) {
            fail(e.toString());
        }
    }

    @Test
    public void cacheImageWithBytes() {
        Photo photo = buildPhotoForImageCacher();
        String base64Bytes = photo.getImageFilePath();
        byte[] data = Base64.decode(base64Bytes, Base64.DEFAULT);
        try {
            assertTrue(imageCacher.cacheImage(photo, data));
        } catch (IOException e) {
            fail(e.toString());
        }
    }

    private Photo buildPhotoForImageCacher() {
        Gson gson = new Gson();
        Photo photo = gson.fromJson(Fakes.PHOTO_RESULT, Photo.class);
        String fileName = String.format("%s.jpg", photo.getId());
        imageFile = new File(CURRENT_DIR, fileName);
        String imageFilePath = imageFile.getAbsolutePath();
        educateMock(fileName);
        photo = Fakes.buildFakePhoto(photo.getId(), imageFilePath, photo.getDescription(), photo.isLiked(), photo.isDeleteable(), photo.getCommentCount());
        return photo;
    }

}

@@ -2174,22 +2174,19 @@
 ate 
-File imageFile
+Photo photo
 ;%0A%0A 
@@ -2814,24 +2814,108 @@
 earDown() %7B%0A
+        if (photo != null) %7B%0A            File imageFile = photo.getImageFile();%0A    
         if (
@@ -2959,32 +2959,36 @@
 ())%0A            
+    
 imageFile.delete
@@ -2987,24 +2987,34 @@
 e.delete();%0A
+        %7D%0A
     %7D%0A%0A    @
@@ -3165,38 +3165,32 @@
 age() %7B%0A        
-Photo 
 photo = buildPho
@@ -3201,32 +3201,92 @@
 rImageCacher();%0A
+        educateMock(String.format(photo.getId() + %22.jpg%22));%0A
         try %7B%0A  
@@ -3570,38 +3570,32 @@
 hed() %7B%0A        
-Photo 
 photo = buildPho
@@ -3606,32 +3606,92 @@
 rImageCacher();%0A
+        educateMock(String.format(photo.getId() + %22.jpg%22));%0A
         try %7B%0A  
@@ -3943,47 +3943,153 @@
     
-Photo photo = buildPhotoF
+Gson gson = new Gson();%0A        photo = gson.fromJson(Fakes.PHOTO_RESULT, Photo.class);%0A        educateMock(String.f
 or
-I
 ma
-geCacher(
+t(photo.getId() + %22.jpg%22)
 );%0A 
@@ -4453,22 +4453,16 @@
         
-Photo 
 photo = 
@@ -4571,32 +4571,32 @@
 o.getId());%0A
-
         
 imageFile = 
@@ -4575,32 +4575,37 @@
 tId());%0A        
+File 
 imageFile = new 

fix unit test