 java.util.function.BiConsumer;

import static java.lang.String.format;
import static org.ericghara.argument.Id.AppArg.*;
import static org.ericghara.argument.Id.ArgGroupKey.*;

@Component
@RequiredArgsConstructor
@Slf4j
public class ResultsPrinter implements ApplicationListener<ApplicationReadyEvent> {

    private final FileChecker checker;
    private final FoundArgs<AppArg,
            ArgDefinition, SingleValueArg> foundArgs;
    private String hashFormat;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        var valid = checker.getValid();
        var invalid = checker.getInvalid();
        hashFormat = "%-" + selectHashSize() + "s";
        var printer = selectPrinter();
        printer.accept(valid, invalid);
    }

    BiConsumer<List<HashPair>, List<HashPair>> selectPrinter() {
        var mode = foundArgs.getFound(MODE).getArgIds();
        // generator signature is a subset of checker, so MUST check for checker first
        if (mode.contains(DESTINATION) ) {
            return this::checkerPrinter;
        }
        else if (mode.contains(SNAPSHOT) ) {
            return this::snapshotPrinter;
        }
        else {
            throw new ImproperApplicationArgumentsException(
                    "Could not determine signature for ResultsPrinter");
        }
    }

    int selectHashSize() {
        var hashAlgos = foundArgs.getFound(HASH_ALGO)
                                               .getArgIds()
                                               .iterator();
        if (!hashAlgos.hasNext() ) {
            throw new ImproperApplicationArgumentsException("Cannot configure ResultsPrinter.  No hashAlgo specified.");
        }
        var hashAlgo = hashAlgos.next();
        log.debug("Setting column width for " + hashAlgo + " hash algorithm");

        return switch (hashAlgo) {
            case NO_HASH -> 12;
            case MD5 -> 32;
            case SHA_1 -> 40;
            case SHA_256 -> 64;
            default -> throw new ImproperApplicationArgumentsException("Unrecognized Hash Algo: " + hashAlgo);
        };
    }

    void snapshotPrinter(List<HashPair> valid, List<HashPair> invalid) {
        if (invalid.isEmpty() ) {
            System.out.printf("Unrecoverable error.  Could not hash the following files:%n");
            invalid.forEach( (r) -> System.out.println(r.expected().path() ) );
            return;
        }
        var path = foundArgs.getFound(REQUIRED)
                                  .get(SOURCE_FILE_LIST)
                                  .value();
        File file = new File(path);
        if (file.exists() ) {
            throw new ImproperApplicationArgumentsException(
                    format("A file already exists at %s. Cannot overwrite an existing file.", path ) );
        }
        try (PrintWriter hashList = new PrintWriter(new BufferedWriter(new FileWriter(file) ) ) ){
            invalid.forEach( (r) -> hashList.printf("%s  %s%n", r.found().path(), r.found().hash() ) );
        } catch (Exception e) {
            throw new UnrecoverableFileIOException(format("Error while writing a srcFileList to: %s", path) );
        }
        System.out.printf("Success.  A srcFileList was written to: %s%n", path);
    }

    void checkerPrinter(List<HashPair> valid, List<HashPair> invalid) {
        System.out.printf("%n>> Valid << %n%n");
        System.out.printf(hashFormat + "  Path%n", "Hash");
        valid.forEach( (r) -> System.out.printf(hashFormat + "  %s%n", r.found().hash(), r.found().path()) );
        if (!invalid.isEmpty() ) {
            System.out.printf("%n>> Invalid << %n%n");
            System.out.printf(hashFormat + "  " + hashFormat + "  %s%n", "Expected", "Found", "Path");
            invalid.forEach((r) -> System.out.printf(hashFormat + "  " + hashFormat + "  %s%n",
                    r.expected().hash(), r.found().hash(), r.found().path()));
        }
        System.out.printf("%nSummary: %d of %d are valid%n", valid.size(), valid.size()+invalid.size() );
    }
}
Azenby Road was a rare thing in Peckham: a street with its own playground. Albeit only a bare patch of ground, it was an obvious magnet for local youngsters, as was the novelty, on this occasion, of having their photograph taken.
The site, sandwiched between Lyndhurst Grove and the railway, was an awkward one for the builders; too small for two streets and too large for one. This compromise resulted in houses with very small gardens, but having a shared open space in the middle of the street.
The houses have been demolished and the play area expanded into Warwick Gardens.Whether hiking, encouraging women in technology, sharing insights on diversity in the workplace, or pursuing professional interests, SAP Mentor Karin Tillotson is an inspiration in many ways.
She has learned that sometimes it can take one article, one colleague, or one community connection to spark a rewarding new career journey.
I have had the incredible pleasure & fortune of knowing and working with Karin for over 10 years in various projects which are passionate for each of us from tennis anyone to women in technology. Recently I caught up with Karin to find out about her approach to work- life balance as well as her many professional experiences. It was insightful to hear her views on Data Archiving and Information Lifecycle Management (ILM), Data Volume Management, and SAP Basis Administration with Fortune500 organizations, customers, and peers around the globe.
Stacey Fish (SF): Tell us about your career journey in the Oil & Gas and Beverage industries. What got you interested in what you do now? Did it start back in your university days or more along the way (or both)?
Karin Tillotson (KT): My IT career journey started a long time ago in a galaxy far, far away in the 80’s. I was still trying to figure out what I wanted to do with my life when I read an article in Time magazine about the Future of Computers. The article made me interested in learning more.
I went back to school and learned Programming — Assembler, COBOL, RPG III, etcetera — and got my first IT job working with System/36, System/38, and then the AS/400. I started out programming, but eventually moved into a System Administrator role. I was working at The Pillsbury Company when I first became an SAP Basis Administrator. This is where I first started learning about SAP Data Archiving in 1999.
SAP Data Archiving turned out to be a great fit for me as I can communicate with technical teams as well as business teams. This journey took me to other companies as opportunities came up, such as Valero Energy Corporation and The Coca-Cola Company. It has been very interesting to work for companies in different industries as the data that is generated is not the same so additional archive objects are needed.
SF: Many of your family and friends know that you enjoy hiking both near and far – from Georgia in the US all the way to the Philippines where you bridged the great outdoors, data, and mobile apps. Are you still hiking? How does it contribute to your success as an independent SAP Information Lifecycle Management and Archiving Consultant?
KT: Yes, I love to hike and am still hiking whenever I can fit it into my schedule. Besides the Philippines, my international hiking adventures include New Zealand South Island, Spain, the Galapagos Islands, and Peru. I do have 2 upcoming hiking trips planned in the Grand Tetons and the Smoky Mountains.
Hiking is where I can relax and recharge after a busy work week. When you are hiking, you also must stay focused as one wrong step could be disastrous. Being in nature and disconnected from the world gives me positive energy which in turn helps me be a better SAP ILM and Archiving Consultant.
KT: I am one of the original SAP Mentors. I was a Mentor before the Mentor program started, as I was one of the few in the SAP Net Promoter Program, which evolved into the SAP Mentor program. One of the reasons I was nominated was due to all the SAP Archiving presentations I had given, as well as the volunteer work I had done for Americas’ SAP Users’ Group (ASUG).
Participating as an SAP Mentor has always been special to me. I love being part of the Community and sharing knowledge. Additionally, it has provided me the opportunity to meet some remarkable people. It has been a privilege to get to know colleagues all over the world in the SAP Community.
SF: Given