package de.nenick.espressomacchiato.elements;

import android.app.Activity;
import android.content.res.Configuration;
import android.support.annotation.NonNull;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.Espresso;
import android.support.test.espresso.NoMatchingViewException;
import android.support.test.espresso.ViewAssertion;
import android.view.View;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
import static de.nenick.espressomacchiato.actions.OrientationChangeAction.orientationLandscape;
import static de.nenick.espressomacchiato.actions.OrientationChangeAction.orientationPortrait;

/**
 * Actions you can do with android devices.
 */
public class EspDevice {

    /**
     * Click androids back button.
     * <p/>
     * This is not the up button from an ActionBar.
     */
    public void clickBackButton() {
        Espresso.pressBack();
    }

    /**
     * Rotate screen to portrait.
     * <p/>
     * Orientation is only changed if activity does not specify android:screenOrientation.
     */
    public void rotateToPortrait() {
        onView(isRoot()).perform(orientationPortrait());
    }

    /**
     * Rotate screen to landscape.
     * <p/>
     * Orientation is only changed if activity does not specify android:screenOrientation.
     */
    public void rotateToLandscape() {
        onView(isRoot()).perform(orientationLandscape());
    }

    /**
     * Check if activity orientation is portrait.
     */
    public void assertOrientationIsPortrait() {
        onView(isRoot()).check(orientation(Configuration.ORIENTATION_PORTRAIT));
    }

    /**
     * Check if activity orientation is landscape.
     */
    public void assertOrientationIsLandscape() {
        onView(isRoot()).check(orientation(Configuration.ORIENTATION_LANDSCAPE));
    }

    @NonNull
    private ViewAssertion orientation(final int expectedOrientation) {
        return new ViewAssertion() {
            @Override
            public void check(View view, NoMatchingViewException noViewFoundException) {
                if (noViewFoundException != null) {
                    throw noViewFoundException;
                }

                int requestedOrientation = ((Activity) view.getContext()).getRequestedOrientation();
                if (currentOrientation() != expectedOrientation) {
                    String errorMessage = "expected device orientation "
                            + orientationAsString(expectedOrientation)
                            + " but was " + orientationAsString(currentOrientation());
                    errorMessage += " and requested orientation is " + requestedOrientation;
                    throw new AssertionError(errorMessage);
                }
            }
        };
    }

    private static String orientationAsString(int orientation) {
        switch (orientation) {
            case Configuration.ORIENTATION_PORTRAIT:
                return "PORTRAIT";
            case Configuration.ORIENTATION_LANDSCAPE:
                return "LANDSCAPE";
            default:
                return "UNDEFINED";
        }
    }

    private int currentOrientation() {
        return InstrumentationRegistry.getContext().getResources().getConfiguration().orientation;
    }

}

@@ -2012,52 +2012,817 @@
 new 
-ViewAssertion() %7B%0A            @Override%0A    
+OrientationAssertion(expectedOrientation);%0A    %7D%0A%0A    private static String orientationAsString(int orientation) %7B%0A        switch (orientation) %7B%0A            case Configuration.ORIENTATION_PORTRAIT:%0A                return %22PORTRAIT%22;%0A            case Configuration.ORIENTATION_LANDSCAPE:%0A                return %22LANDSCAPE%22;%0A            default:%0A                return %22UNDEFINED%22;%0A        %7D%0A    %7D%0A%0A    private int currentOrientation() %7B%0A        return InstrumentationRegistry.getContext().getResources().getConfiguration().orientation;%0A    %7D%0A%0A    private class OrientationAssertion implements ViewAssertion %7B%0A        private final int expectedOrientation;%0A%0A        public OrientationAssertion(int expectedOrientation) %7B%0A            this.expectedOrientation = expectedOrientation;%0A        %7D%0A%0A        @Override%0A
     
@@ -2910,28 +2910,24 @@
             
-    
 if (noViewFo
@@ -2962,28 +2962,24 @@
             
-  
-  
 throw noView
@@ -3002,35 +3002,27 @@
             
-    %7D%0A%0A    
+%7D%0A%0A
             
@@ -3114,28 +3114,24 @@
             
-    
 if (currentO
@@ -3161,36 +3161,32 @@
 dOrientation) %7B%0A
-    
                 
@@ -3262,20 +3262,16 @@
         
-   
- 
 + orient
@@ -3305,20 +3305,16 @@
 tation)%0A
-    
         
@@ -3404,20 +3404,16 @@
         
-    
 errorMes
@@ -3489,28 +3489,24 @@
             
- 
-   
 throw new As
@@ -3537,36 +3537,32 @@
 e);%0A            
-    
 %7D%0A            %7D%0A
@@ -3559,523 +3559,14 @@
     
- 
-   
 %7D%0A    
- 
-   %7D;%0A    %7D%0A%0A    private static String orientationAsString(int orientation) %7B%0A        switch (orientation) %7B%0A            case Configuration.ORIENTATION_PORTRAIT:%0A                return %22PORTRAIT%22;%0A            case Configuration.ORIENTATION_LANDSCAPE:%0A                return %22LANDSCAPE%22;%0A            default:%0A                return %22UNDEFINED%22;%0A        %7D%0A    %7D%0A%0A    private int currentOrientation() %7B%0A        return InstrumentationRegistry.getContext().getResources().getConfiguration().orientation;%0A    %7D%0A
+%7D
 %0A%7D%0A

remove anonymous class