// Path: approval-core/src/main/java/com/github/approval/Reporter.java
// public interface Reporter {
//     /**
//      * Called by an {@link com.github.approval.Approval} object when values don't match in the approval process.
//      *
//      * @param oldValue the old value that was found in fileForVerification from old runs
//      * @param newValue the new value that was passed for verification
//      * @param fileForVerification the file for this approval value
//      * @param fileForApproval the file for the new content
//      */
//     void notTheSame(byte[] oldValue, File fileForVerification, byte[] newValue, File fileForApproval);
// 
//     /**
//      * Called by an {@link com.github.approval.Approval} object when a value for verification is produced but no old.
//      *
//      * @param value the new value that came from the verification
//      * @param fileForApproval the approval file(this contains the value that was passed in)
//      * @param fileForVerification the file for the this new approval value  @return true if the new value is approved and false otherwise
//      */
//     void approveNew(byte[] value, File fileForApproval, File fileForVerification);
// 
//     /**
//      * A method to check if this reporter is supported for the following file type or environment! Reporters are
//      * different for different platforms and file types and this in conjuction with {@link
//      * com.github.approval.reporters.Reporters#firstWorking} will allow you to plug different reporters for different
//      * environments(CI, Windows, Linux, MacOS, etc).
//      *
//      * @param fileForApproval the file that we want to approve
//      * @return true if we can approve the file and false otherwise
//      */
//     boolean canApprove(File fileForApproval);
// }


import java.io.File;
import java.lang.reflect.Method;
import java.util.Locale;
import com.github.approval.Reporter;
package com.github.approval.reporters;

/*
 * #%L
 * com.github.nikolavp:approval-core
 * %%
 * Copyright (C) 2014 Nikolavp
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */



/**
 * A reporter that uses a reporter specified in a property value or environment variable.
 * <p>
 * The property name is used as is and the environment variable is build by replacing '.' with '_'. So the property
 * <b>"default.approval.reporter"</b> will be searched as in system properties (-D parameters) and as
 * <b>"DEFAULT_APPROVAL_REPORTER"</b> in environment variables.
 *
 * </p>
 * <p>This reporter is perfect for
 * first parameter in {@link Reporters#firstWorking(com.github.approval.Reporter...)}.
 * </p>
 *
 *
 * @see #getInstance(String)
 */
public final class SystemPropertyReporter implements Reporter {

    private Reporter reporter;

    private SystemPropertyReporter(String classOrFactoryMethod) {
        try {
            Class<?> aClass = Class.forName(classOrFactoryMethod);
            try {
                Object instance = aClass.getConstructor().newInstance();
                if (!(instance instanceof Reporter)) {
                    throw new AssertionError("We got an instance of " + aClass + " but it isn't a reporter!");
                }
                this.reporter = (Reporter) instance;
            } catch (ReflectiveOperationException e) {
                throw new AssertionError(aClass + " exists but we couldn't instantiate it!", e);
            }
        } catch (ClassNotFoundException e) {
            int i = classOrFactoryMethod.lastIndexOf('.');
            if (i == -1 || i + 1 == classOrFactoryMethod.length()) {
                throw new AssertionError("Couldn't instantiate class " + classOrFactoryMethod, e);
            }
            String possibleClass = classOrFactoryMethod.substring(0, i);
            String method = classOrFactoryMethod.substring(i + 1);

            try {
                Class<?> aClass = Class.forName(possibleClass);
                try {
                    Method m = aClass.getMethod(method);

                    Object instance = m.invoke(null);

                    if (!(instance instanceof Reporter)) {
                        throw new AssertionError("The instance that was returned from the factory method " + method + " in " + aClass + " is not a reporter");
                    }

// Path: approval-core/src/main/java/com/github/approval/Reporter.java
// public interface Reporter {
//     /**
//      * Called by an {@link com.github.approval.Approval} object when values don't match in the approval process.
//      *
//      * @param oldValue the old value that was found in fileForVerification from old runs
//      * @param newValue the new value that was passed for verification
//      * @param fileForVerification the file for this approval value
//      * @param fileForApproval the file for the new content
//      */
//     void notTheSame(byte[] oldValue, File fileForVerification, byte[] newValue, File fileForApproval);
// 
//     /**
//      * Called by an {@link com.github.approval.Approval} object when a value for verification is produced but no old.
//      *
//      * @param value the new value that came from the verification
//      * @param fileForApproval the approval file(this contains the value that was passed in)
//      * @param fileForVerification the file for the this new approval value  @return true if the new value is approved and false otherwise
//      */
//     void approveNew(byte[] value, File fileForApproval, File fileForVerification);
// 
//     /**
//      * A method to check if this reporter is supported for the following file type or environment! Reporters are
//      * different for different platforms and file types and this in conjuction with {@link
//      * com.github.approval.reporters.Reporters#firstWorking} will allow you to plug different reporters for different
//      * environments(CI, Windows, Linux, MacOS, etc).
//      *
//      * @param fileForApproval the file that we want to approve
//      * @return true if we can approve the file and false otherwise
//      */
//     boolean canApprove(File fileForApproval);
// }


// Path: approval-core/src/main/java/com/github/approval/reporters/SystemPropertyReporter.java
import java.io.File;
import java.lang.reflect.Method;
import java.util.Locale;
import com.github.approval.Reporter;

package com.github.approval.reporters;

/*
 * #%L
 * com.github.nikolavp:approval-core
 * %%
 * Copyright (C) 2014 Nikolavp
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */



/**
 * A reporter that uses a reporter specified in a property value or environment variable.
 * <p>
 * The property name is used as is and the environment variable is build by replacing '.' with '_'. So the property
 * <b>"default.approval.reporter"</b> will be searched as in system properties (-D parameters) and as
 * <b>"DEFAULT_APPROVAL_REPORTER"</b> in environment variables.
 *
 * </p>
 * <p>This reporter is perfect for
 * first parameter in {@link Reporters#firstWorking(com.github.approval.Reporter...)}.
 * </p>
 *
 *
 * @see #getInstance(String)
 */
public final class SystemPropertyReporter implements Reporter {

    private Reporter reporter;

    private SystemPropertyReporter(String classOrFactoryMethod) {
        try {
            Class<?> aClass = Class.forName(classOrFactoryMethod);
            try {
                Object instance = aClass.getConstructor().newInstance();
                if (!(instance instanceof Reporter)) {
                    throw new AssertionError("We got an instance of " + aClass + " but it isn't a reporter!");
                }
                this.reporter = (Reporter) instance;
            } catch (ReflectiveOperationException e) {
                throw new AssertionError(aClass + " exists but we couldn't instantiate it!", e);
            }
        } catch (ClassNotFoundException e) {
            int i = classOrFactoryMethod.lastIndexOf('.');
            if (i == -1 || i + 1 == classOrFactoryMethod.length()) {
                throw new AssertionError("Couldn't instantiate class " + classOrFactoryMethod, e);
            }
            String possibleClass = classOrFactoryMethod.substring(0, i);
            String method = classOrFactoryMethod.substring(i + 1);

            try {
                Class<?> aClass = Class.forName(possibleClass);
                try {
                    Method m = aClass.getMethod(method);

                    Object instance = m.invoke(null);

                    if (!(instance instanceof Reporter)) {
                        throw new AssertionError("The instance that was returned from the factory method " + method + " in " + aClass + " is not a reporter");
                    }

                    this.reporter = (Reporter) instance;