/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~ Licensed to the Apache Software Foundation (ASF) under one
 ~ or more contributor license agreements.  See the NOTICE file
 ~ distributed with this work for additional information
 ~ regarding copyright ownership.  The ASF licenses this file
 ~ to you 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.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
package org.apache.sling.cli.impl.release;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.mail.internet.InternetAddress;

import org.apache.sling.cli.impl.Command;
import org.apache.sling.cli.impl.Credentials;
import org.apache.sling.cli.impl.CredentialsService;
import org.apache.sling.cli.impl.DateProvider;
import org.apache.sling.cli.impl.ExecutionMode;
import org.apache.sling.cli.impl.mail.Email;
import org.apache.sling.cli.impl.mail.Mailer;
import org.apache.sling.cli.impl.mail.VoteThreadFinder;
import org.apache.sling.cli.impl.nexus.StagingRepository;
import org.apache.sling.cli.impl.nexus.RepositoryService;
import org.apache.sling.cli.impl.people.Member;
import org.apache.sling.cli.impl.people.MembersFinder;
import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.osgi.framework.ServiceReference;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.mockStatic;

@RunWith(PowerMockRunner.class)
@PowerMockIgnore({
                         // https://github.com/powermock/powermock/issues/864
                         "com.sun.org.apache.xerces.*",
                         "javax.xml.*",
                         "org.w3c.dom.*"
                 })
public class TallyVotesCommandTest {

    @Before
    public void beforeClass() {
        DateProvider dateProvider = mock(DateProvider.class);
        when(dateProvider.getCurrentDateForEmailHeader()).thenReturn("Thu, 1 Jan 1970 01:00:00 +0100");
        osgiContext.registerService(DateProvider.class, dateProvider);
    }

    @Rule
    public final OsgiContext osgiContext = new OsgiContext();

    @Test
    @PrepareForTest({LoggerFactory.class})
    public void testDryRun() throws Exception {
        mockStatic(LoggerFactory.class);
        Logger logger = mock(Logger.class);
        when(LoggerFactory.getLogger(TallyVotesCommand.class)).thenReturn(logger);
        List<Email> thread = new ArrayList<>(){{
            add(mockEmail("johndoe@apache.org", "John Doe"));
            add(mockEmail("alice@apache.org", "Alice"));
            add(mockEmail("bob@apache.org", "Bob"));
            add(mockEmail("charlie@apache.org", "Charlie"));
            add(mockEmail("daniel@apache.org", "Daniel"));
            add(mockEmail("johndoe@apache.org", "John Doe"));
        }};
        prepareExecution(mock(Mailer.class), thread);
        TallyVotesCommand tallyVotesCommand = spy(new TallyVotesCommand());
        ReusableCLIOptions reusableCLIOptions = mock(ReusableCLIOptions.class);
        Whitebox.setInternalState(reusableCLIOptions, "executionMode", ExecutionMode.DRY_RUN);
        Whitebox.setInternalState(tallyVotesCommand, "repositoryId", 123);
        Whitebox.setInternalState(tallyVotesCommand, "reusableCLIOptions", reusableCLIOptions);
        osgiContext.registerInjectActivateService(tallyVotesCommand);
        ServiceReference<?> reference =
                osgiContext.bundleContext().getServiceReference(Command.class.getName());
        Command command = (Command) osgiContext.bundleContext().getService(reference);
        command.run();
        verify(logger).info(
                "From: John Doe <johndoe@apache.org>\n" +
                "To: \"Sling Developers List\" <dev@sling.apache.org>\n" +
                "Reply-To: \"Sling Developers List\" <dev@sling.apache.org>\n" +
                "Date: Thu, 1 Jan 1970 01:00:00 +0100\n" +
                "Subject: [RESULT] [VOTE] Release Apache Sling CLI Test 1.0.0\n" +
                "\n" +
                "Hi,\n" +
                "\n" +
                "The vote has passed with the following result:\n" +
                "\n" +
                "+1 (binding): Alice, Bob, Charlie, John Doe\n" +
                "+1 (non-binding): Daniel\n" +
                "\n" +
                "I will copy this release to the Sling dist directory and\n" +
                "promote the artifacts to the central Maven repository.\n" +
                "\n" +
                "Regards,\n" +
                "John Doe\n"
        );
    }

    @Test
    @PrepareForTest({LoggerFactory.class})
    public void testDryRunNotEnoughBindingVotes() throws Exception {
        mockStatic(LoggerFactory.class);
        Logger logger = mock(Logger.class);
        when(LoggerFactory.getLogger(TallyVotesCommand.class)).thenReturn(logger);
        List<Email> thread = new ArrayList<>(){{
            add(mockEmail("johndoe@apache.org", "John Doe"));
            add(mockEmail("alice@apache.org", "Alice"));
            add(mockEmail("bob@apache.org", "Bob"));
            add(mockEmail("daniel@apache.org", "Daniel"));
        }};
        prepareExecution(mock(Mailer.class), thread);
        TallyVotesCommand tallyVotesCommand = spy(new TallyVotesCommand());
        ReusableCLIOptions reusableCLIOptions = mock(ReusableCLIOptions.class);
        Whitebox.setInternalState(reusableCLIOptions, "executionMode", ExecutionMode.DRY_RUN);
        Whitebox.setInternalState(tallyVotesCommand, "repositoryId", 123);
        Whitebox.setInternalState(tallyVotesCommand, "reusableCLIOptions", reusableCLIOptions);
        osgiContext.registerInjectActivateService(tallyVotesCommand);
        ServiceReference<?> reference =
                osgiContext.bundleContext().getServiceReference(Command.class.getName());
        Command command = (Command) osgiContext.bundleContext().getService(reference);
        command.run();
        verify(logger).info(
                "Release {} does not have at least 3 binding votes.",
                "Apache Sling CLI Test 1.0.0"
        );

    }

    @Test
    public void testAuto() throws Exception {
        List<Email> thread = new ArrayList<>(){{
            add(mockEmail("johndoe@apache.org", "John Doe"));
            add(mockEmail("alice@apache.org", "Alice"));
            add(mockEmail("bob@apache.org", "Bob"));
            add(mockEmail("charlie@apache.org", "Charlie"));
            add(mockEmail("daniel@apache.org", "Daniel"));
            add(mockEmail("johndoe@apache.org", "John Doe"));
        }};
        Mailer mailer = mock(Mailer.class);
        prepareExecution(mailer, thread);
        TallyVotesCommand tallyVotesCommand = spy(new TallyVotesCommand());
        ReusableCLIOptions reusableCLIOptions = mock(ReusableCLIOptions.class);
        Whitebox.setInternalState(reusableCLIOptions, "executionMode", ExecutionMode.AUTO);
        Whitebox.setInternalState(tallyVotesCommand, "repositoryId", 123);
        Whitebox.setInternalState(tallyVotesCommand, "reusableCLIOptions", reusableCLIOptions);
        osgiContext.registerInjectActivateService(tallyVotesCommand);
        ServiceReference<?> reference =
                osgiContext.bundleContext().getServiceReference(Command.class.getName());
        Command command = (Command) osgiContext.bundleContext().getService(reference);
        command.run();
        verify(mailer).send(
                "From: John Doe <johndoe@apache.org>\n" +
                        "To: \"Sling Developers List\" <dev@sling.apache.org>\n" +
                        "Reply-To: \"Sling Developers List\" <dev@sling.apache.org>\n" +
                        "Date: Thu, 1 Jan 1970 01:00:00 +0100\n" +
                        "Subject: [RESULT] [VOTE] Release Apache Sling CLI Test 1.0.0\n" +
                        "\n" +
                        "Hi,\n" +
                        "\n" +
                        "The vote has passed with the following result:\n" +
                        "\n" +
                        "+1 (binding): Alice, Bob, Charlie, John Doe\n" +
                        "+1 (non-binding): Daniel\n" +
                        "\n" +
                        "I will copy this release to the Sling dist directory and\n" +
                        "promote the artifacts to the central Maven repository.\n" +
                        "\n" +
                        "Regards,\n" +
                        "John Doe\n"
        );
    }

    private Email mockEmail(String address, String name) throws Exception {
        Email email = mock(Email.class);
        when(email.getBody()).thenReturn("+1");
        when(email.getFrom()).thenReturn(new InternetAddress(address, name));
        return email;
    }

    private void prepareExecution(Mailer mailer, List<Email> thread) throws IOException {
        CredentialsService credentialsService = mock(CredentialsService.class);
        when(credentialsService.getAsfCredentials()).thenReturn(new Credentials("johndoe", "secret"));

        MembersFinder membersFinder = spy(new MembersFinder());
        Set<Member> members = new HashSet<>(){{
            add(new Member("johndoe", "John Doe", true));
            add(new Member("alice", "Alice", true));
            add(new Member("bob", "Bob", true));
            add(new Member("charlie", "Charlie", true));
            add(new Member("daniel", "Daniel", false));
        }};
        Whitebox.setInternalState(membersFinder, "members", members);
        Whitebox.setInternalState(membersFinder, "lastCheck", System.currentTimeMillis());

        StagingRepository stagingRepository = mock(StagingRepository.class);
        when(stagingRepository.getDescription()).thenReturn("Apache Sling CLI Test 1.0.0");
        RepositoryService repositoryService = mock(RepositoryService.class);
        when(repositoryService.find(123)).thenReturn(stagingRepository);

        VoteThreadFinder voteThreadFinder = mock(VoteThreadFinder.class);
        when(voteThreadFinder.findVoteThread("CLI Test 1.0.0")).thenReturn(thread);

        osgiContext.registerService(CredentialsService.class, credentialsService);
        osgiContext.registerInjectActivateService(membersFinder);
        osgiContext.registerService(RepositoryService.class, repositoryService);
        osgiContext.registerService(VoteThreadFinder.class, voteThreadFinder);
        osgiContext.registerService(Mailer.class, mailer);
    }
}
