/*
 * Jalview - A Sequence Alignment Editor and Viewer (2.11.5.0)
 * Copyright (C) 2025 The Jalview Authors
 * 
 * This file is part of Jalview.
 * 
 * Jalview is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation, either version 3
 * of the License, or (at your option) any later version.
 *  
 * Jalview is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty 
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
 * PURPOSE.  See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
 * The Jalview Authors are detailed in the 'AUTHORS' file.
 */
package jalview.bin;

import java.util.Date;
import java.util.List;

import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import jalview.api.AlignViewportI;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
import jalview.gui.AlignmentPanel;
import jalview.gui.Desktop;
import jalview.gui.JvOptionPane;
import jalview.gui.StructureViewerBase;

public class CommandsTest2
{
  @BeforeClass(alwaysRun = true)
  public static void setUpBeforeClass() throws Exception
  {
    Cache.loadProperties("test/jalview/bin/commandsTest.jvprops");
    Date oneHourFromNow = new Date(
            System.currentTimeMillis() + 3600 * 1000);
    Cache.setDateProperty("JALVIEW_NEWS_RSS_LASTMODIFIED", oneHourFromNow);
    if (Desktop.instance != null)
      Desktop.instance.closeAll_actionPerformed(null);

  }

  @AfterClass(alwaysRun = true)
  public static void resetProps()
  {
    Cache.loadProperties("test/jalview/testProps.jvprops");
  }

  @BeforeClass(alwaysRun = true)
  public void setUpJvOptionPane()
  {
    JvOptionPane.setInteractiveMode(false);
    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
  }

  @AfterMethod(alwaysRun = true)
  public void tearDown()
  {
    Desktop.closeDesktop();
  }

  @Test(
    groups =
    { "Functional", "testTask1" },
    dataProvider = "structureOpeningArgsParams",
    singleThreaded = true)
  public void do_structureOpeningArgsTest(String cmdLine, int seqNum,
          int annNum, int pdbPerSeqNum, int viewerNum)
  {
    _do_structureOpeningArgsTest(cmdLine, seqNum, annNum, pdbPerSeqNum,
            viewerNum);
  }

  @Test(
    groups =
    { "Network", "testTask1" },
    dataProvider = "structureOpeningArgsNetworkParams",
    singleThreaded = true)
  public void do_network_structureOpeningArgsTest(String cmdLine,
          int seqNum, int annNum, int pdbPerSeqNum, int viewerNum)
  {
    _do_structureOpeningArgsTest(cmdLine, seqNum, annNum, pdbPerSeqNum,
            viewerNum);
  }

  /*
   * Actual test logic - called by different groups with different data providers
   */
  public void _do_structureOpeningArgsTest(String cmdLine, int seqNum,
          int annNum, int strucPerSeqNum, int viewerNum)
  {
    String[] args = cmdLine.split("\\s+");

    CommandsTest.callJalviewMain(args);
    while (Desktop.instance != null
            && Desktop.instance.operationsAreInProgress())
    {
      try
      {
        // sleep for slow build server to open annotations and viewer windows
        Thread.sleep(viewerNum * 50);
      } catch (InterruptedException e)
      {
        e.printStackTrace();
      }
    }
    ;

    AlignFrame[] afs = Desktop.getDesktopAlignFrames();
    Assert.assertNotNull(afs);
    Assert.assertTrue(afs.length > 0);

    AlignFrame af = afs[0];
    Assert.assertNotNull(af);

    AlignmentPanel ap = af.alignPanel;
    Assert.assertNotNull(ap);

    AlignmentI al = ap.getAlignment();
    Assert.assertNotNull(al);

    List<SequenceI> seqs = al.getSequences();
    Assert.assertNotNull(seqs);

    if (seqNum > -1)
    {
      Assert.assertEquals(seqs.size(), seqNum, "Wrong number of sequences");
    }

    AlignViewportI av = ap.getAlignViewport();
    Assert.assertNotNull(av);

    AlignmentAnnotation[] aas = al.getAlignmentAnnotation();
    int visibleAnn = 0;
    int dcount = 0;

    if (strucPerSeqNum > -1)
    {
      for (AlignmentAnnotation aa : aas)
      {
        if (aa.visible)
          visibleAnn++;
        if (aa.sequenceRef != null)
        {
          Assert.assertEquals(
                  aa.sequenceRef.getDatasetSequence().getAllPDBEntries()
                          .size(),
                  strucPerSeqNum,
                  "Unexpected number of structures for sequence");
        }
      }
    }

    if (annNum > -1)
    {
      Assert.assertEquals(visibleAnn, annNum,
              "Wrong number of visible annotations");
    }

    if (viewerNum > -1)
    {
      List<StructureViewerBase> openViewers = Desktop.instance
              .getStructureViewers(ap, null);
      Assert.assertNotNull(openViewers);
      int count = 0;
      for (StructureViewerBase svb : openViewers)
      {
        if (svb.isVisible())
        {
          count++;
        }
      }
      Assert.assertEquals(count, viewerNum,
              "Wrong number of structure viewers opened");
    }
  }

  @DataProvider(name = "structureOpeningArgsNetworkParams")
  public Object[][] structureOpeningArgsNetworkParams()
  {
    /*
      String cmdLine,
      int seqNum,
      int annNum,
      int strucPerSeq,
      int structureViewerNum,
     */
    return new Object[][] {
        //
        /*
         * check import of structure and metadata via URL
         */
        { "--gui --nonews --nosplash --debug "
                + "--open https://www.jalview.org/examples/uniref50.fa "
                + "--colour=gecos-flower "
                + "--structure=[seqid=FER1_SPIOL]https://www.jalview.org/examples/AlphaFold/AF-P00221-F1-model_v4.cif "
                + "--paematrix=https://www.jalview.org/examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json "
                + "--props=test/jalview/bin/commandsTest2.jvprops1 ",
            15, 7, 1, 1 },
        //
        /*
         * check URL import via 'open='
         */
        { "--gui --nonews --nosplash --debug "
                + "--open=https://www.jalview.org/examples/uniref50.fa "
                + "--colour=gecos-flower "
                + "--structure=[seqid=FER1_SPIOL]https://www.jalview.org/examples/AlphaFold/AF-P00221-F1-model_v4.cif "
                + "--paematrix=https://www.jalview.org/examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json "
                + "--props=test/jalview/bin/commandsTest2.jvprops1 ",
            15, 7, 1, 1 },
        //
        /*
         * check URL import via 'append='
         */
        { "--gui --nonews --nosplash --debug "
                + "--append=https://www.jalview.org/examples/uniref50.fa "
                + "--colour=gecos-flower "
                + "--structure=[seqid=FER1_SPIOL]https://www.jalview.org/examples/AlphaFold/AF-P00221-F1-model_v4.cif "
                + "--paematrix=https://www.jalview.org/examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json "
                + "--props=test/jalview/bin/commandsTest2.jvprops1 ",
            15, 7, 1, 1 }, };
  }

  @DataProvider(name = "structureOpeningArgsParams")
  public Object[][] structureOpeningArgsParams()
  {
    /*
      String cmdLine,
      int seqNum,
      int annNum,
      int strucPerSeq,
      int structureViewerNum,
     */
    String stdargs = "--gui --nonews --nosplash --debug ";
    String stdargs2 = stdargs
            + "--nowebservicediscovery --props=test/jalview/bin/commandsTest.jvprops ";
    return new Object[][] {
        //
        /*
         */
        { stdargs + "--append=examples/uniref50.fa "
                + "--colour=gecos-flower "
                + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif "
                + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json "
                + "--props=test/jalview/bin/commandsTest2.jvprops1 ",
            15, 7, 1, 1 },
        { stdargs + "--append=examples/uniref50.fa "
                + "--colour=gecos-flower "
                + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif "
                + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json "
                + "--props=test/jalview/bin/commandsTest2.jvprops2 ",
            15, 4, 1, 1 },
        { stdargs + "--append=examples/uniref50.fa "
                + "--colour=gecos-flower "
                + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif "
                + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json "
                + "--noshowssannotations "
                + "--props=test/jalview/bin/commandsTest2.jvprops1 ",
            15, 4, 1, 1 },
        { stdargs + "--append=examples/uniref50.fa "
                + "--colour=gecos-flower "
                + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif "
                + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json "
                + "--noshowannotations "
                + "--props=test/jalview/bin/commandsTest2.jvprops1 ",
            15, 3, 1, 1 },
        { stdargs + "--append=examples/uniref50.fa "
                + "--colour=gecos-flower "
                + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif "
                + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json "
                + "--noshowannotations " + "--noshowssannotations "
                + "--props=test/jalview/bin/commandsTest2.jvprops1 ",
            15, 0, 1, 1 },
        { stdargs + "--append=examples/uniref50.fa "
                + "--colour=gecos-flower "
                + "--structure=[seqid=FER1_SPIOL]examples/AlphaFold/AF-P00221-F1-model_v4.cif "
                + "--paematrix=examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json "
                + "--noshowannotations " + "--noshowssannotations "
                + "--props=test/jalview/bin/commandsTest2.jvprops1 ",
            15, 0, 1, 1 },
        { stdargs2 + "--argfile=test/jalview/bin/commandsTest2.argfile1 ",
            16, 19, 5, 3 },
        { stdargs2 + "--argfile=test/jalview/bin/commandsTest2.argfile2 ",
            16, 0, 5, 2 },
        { stdargs2 + "--open=./examples/test_fab41.result/sample.a2m "
                + "--allstructures "
                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb "
                + "--structureviewer=none "
                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4.pdb "
                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2.pdb",
            16, 10, 3, 0 },
        { stdargs2 + "--open=./examples/test_fab41.result/sample.a2m "
                + "--allstructures "
                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb "
                + "--noallstructures " + "--structureviewer=none "
                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_2_model_4.pdb "
                + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_3_model_2.pdb",
            16, 10, 3, 2 },
        // these three are to test that multiple annotations files can be
        // opened
        { stdargs2 + "--open=./examples/plantfdx.fa ", 15, 4, 0, 0 },
        { stdargs2 + "--open=./examples/plantfdx.fa "
                + "--annotations=./examples/testdata/plantfdx.annotations ",
            15, 10, 0, 0 },
        { stdargs2 + "--open=./examples/plantfdx.fa "
                + "--annotations=./examples/testdata/plantfdx.annotations "
                + "--annotations=./examples/testdata/FER1_SPIOL.plddt "
                + "--annotations=./examples/testdata/FER1_SPIOL.paematrix ",
            15, 12, 0, 0 },
        // these 7 are to test that structure viewers can be shared
        { stdargs2 + "--open=./examples/uniref50.fa "
                + "--structure=./examples/AF-P83527-F1-model_v4.cif --seqid=FER_CAPAA "
                + "--structure=./examples/SM-P83527-FER_CAPAA.pdb --seqid=FER_CAPAA --nosuperpose "
                + "--structure=./examples/AlphaFold/AF-P00221-F1-model_v4.pdb --seqid=FER1_SPIOL ",
            -1, -1, -1, 3 },
        { stdargs2 + "--open=./examples/uniref50.fa "
                + "--structure=./examples/AF-P83527-F1-model_v4.cif --seqid=FER_CAPAA --viewerid=id1 "
                + "--structure=./examples/SM-P83527-FER_CAPAA.pdb --seqid=FER_CAPAA --nosuperpose --viewerid=id1 "
                + "--structure=./examples/AlphaFold/AF-P00221-F1-model_v4.pdb --seqid=FER1_SPIOL ",
            -1, -1, -1, 2 },
        { stdargs2 + "--open=./examples/uniref50.fa "
                + "--structure=./examples/AF-P83527-F1-model_v4.cif --seqid=FER_CAPAA --viewerid=id1 "
                + "--structure=./examples/SM-P83527-FER_CAPAA.pdb --seqid=FER_CAPAA --nosuperpose --viewerid=id1 "
                + "--structure=./examples/AlphaFold/AF-P00221-F1-model_v4.pdb --seqid=FER1_SPIOL --viewerid=id2 ",
            -1, -1, -1, 2 },
        { stdargs2 + "--open=./examples/uniref50.fa "
                + "--structure=./examples/AF-P83527-F1-model_v4.cif --seqid=FER_CAPAA --viewerid=id1 "
                + "--structure=./examples/SM-P83527-FER_CAPAA.pdb --seqid=FER_CAPAA --nosuperpose --viewerid=id1 "
                + "--structure=./examples/AlphaFold/AF-P00221-F1-model_v4.pdb --seqid=FER1_SPIOL --viewerid=id1 ",
            -1, -1, -1, 1 },
        { stdargs2 + "--open=./examples/uniref50.fa "
                + "--structuresfile=./examples/structuresfile.txt ",
            -1, -1, -1, 1 },
        { stdargs2 + "--open=./examples/uniref50.fa "
                + "--structuresfile=./examples/structuresfile.txt "
                + "--structure=./examples/SM-P83527-FER_CAPAA.pdb --seqid=FER_CAPAA --nosuperpose --viewerid=id1 "
                + "--structuresfile=./examples/structuresfile2.txt ",
            -1, -1, -1, 3 },
        { stdargs2 + "--open=./examples/uniref50.fa "
                + "--structuresfile=./examples/structuresfile.txt "
                + "--structure=./examples/SM-P83527-FER_CAPAA.pdb --seqid=FER_CAPAA --nosuperpose --viewerid=THIS "
                + "--structuresfile=./examples/structuresfile2.txt ",
            -1, -1, -1, 2 },
        /*
         */
        //
    };
  }
}
