/*

Derby - Class org.apache.derbyTesting.functionTests.tests.jdbcapi.Derby2017LayerATest

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.derbyTesting.functionTests.tests.jdbcapi;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import junit.framework.Test;
import org.apache.derbyTesting.functionTests.util.streams.LoopingAlphabetReader;
import org.apache.derbyTesting.junit.BaseJDBCTestCase;
import org.apache.derbyTesting.junit.BaseTestSuite;
import org.apache.derbyTesting.junit.JDBC;
import org.apache.derbyTesting.junit.TestConfiguration;

/**
 * Tests that inserts with streams whose lengths differs from the the length
 * specified don't insert data into the database when they shouldn't.
 * <p>
 * The test uses various combinations of auto-commit and rollback.
 */
public class Derby2017LayerATest
        extends BaseJDBCTestCase {

    /** The encoding used when generating a byte array from a string. */
    public static final String UTF8 = "UTF-8";

    public Derby2017LayerATest(String name) {
        super(name);
    }

    /**
     * Returns a suite running most of the tests with both the client driver
     * and the embedded driver, and some of the tests only with the client
     * driver.
     *
     * @return A suite of tests.
     */
    public static Test suite() {
        BaseTestSuite ts = new BaseTestSuite();
        ts.addTest(
                TestConfiguration.defaultSuite(Derby2017LayerATest.class));
        // Run the tests below with the client driver only.
        BaseTestSuite clientSuite = new BaseTestSuite("Client only tests");
        clientSuite.addTest(new Derby2017LayerATest(
                "cs_FailedStreamInsertCharBufferBoundaries"));
        clientSuite.addTest(new Derby2017LayerATest(
                "cs_StreamInsertCharBufferBoundary"));
        ts.addTest(TestConfiguration.clientServerDecorator(clientSuite));

        return ts;
    }

    /**
     * Tests inserts around some selected buffer boundaries. This test verifies
     * that the client and server can sucessfully insert values of various
     * lengths. It will work also before the fix for DERBY-2017, but will fail
     * if an incorrect fix is applied.
     */
    public void cs_StreamInsertCharBufferBoundary()
            throws IOException, SQLException {
        rollback();
        Statement stmt = createStatement();
        try {
            stmt.executeUpdate("create table t2017_len (len int, c clob)");
        } catch (SQLException sqle) {
            assertSQLState("X0Y32", sqle);
            stmt.executeUpdate("delete from t2017_len");
        }
        commit();
        setAutoCommit(false);

        // Note that when using layer A streaming the data is converted to
        // UTF-16 on the wire.
        PreparedStatement ps =
                prepareStatement("insert into t2017_len values (?,?)");
        // Test small values.
        for (int i=0; i < 512; i++) {
            ps.setInt(1, i);
            ps.setCharacterStream(2, new LoopingAlphabetReader(i), i);
            ps.executeUpdate();
        }
        commit();

        // Test values at the buffer boundary. Assumes UTF-16 and a ~32 KB
        // transmit buffer.
        for (int i=16000; i < 18000; i++) {
            ps.setInt(1, i);
            ps.setCharacterStream(2, new LoopingAlphabetReader(i), i);
            ps.executeUpdate();
            // Commit periodically.
            if (i % 1000 == 0) {
                commit();
            }
        }
        commit();

        for (int i=32500; i < 33000; i++) {
            ps.setInt(1, i);
            ps.setCharacterStream(2, new LoopingAlphabetReader(i), i);
            ps.executeUpdate();
        }
        commit();

        // Verify the data, basically making sure the status flag isn't
        // included as part of the user data.
        ResultSet rs = stmt.executeQuery("select len, c from t2017_len");
        int rows = 0;
        while (rs.next()) {
            rows++;
            assertEquals(new LoopingAlphabetReader(rs.getInt(1)),
                         rs.getCharacterStream(2));
        }
    }

    /**
     * Runs some failing inserts around buffer boundaries.
     */
    public void cs_FailedStreamInsertCharBufferBoundaries()
            throws IOException, SQLException {
        int[] INSERT;
        for (int i=0; i < 1024; i++) {
            INSERT = new int[] {
                8*1000+i,
                16*1000+i,
                32*1000+i,
                16*1000+i, // This will fail (forced length mismatch)
                32*1000+i, // This will fail (forced length mismatch)
                48*1000+i,
                0+i,
            };
            // We test only one combination of auto-commit and rollback here.
            doInsertTest(INSERT, false, false);
        }
    }

    public void testFailedStreamInsertCharLong()
            throws IOException, SQLException {
        int[] INSERT = new int[] {
            10*1024+1,
            89*1024+3,
            32*1024,
            64*1024, // This will fail (forced length mismatch)
            99*1024, // This will fail (forced length mismatch)
            1,
            197*1024,
        };
        doInsertTest(INSERT, false, false);
        doInsertTest(INSERT, false, true);
        doInsertTest(INSERT, true, false);
        doInsertTest(INSERT, true, true);
    }

    /**
     * Inserts data by reading from streams, where two of these will thrown
     * an {@code IOException}. Data from these streams should not be committed.
     */
    public void testFailedStreamInsertCharIOException()
            throws IOException, SQLException {
        String[] INSERT = new String[] {
                "row 1", "row 2", "row 3",
                "IGNORE", "IGNORE",
                "row 6", "row 7"
            };
        String[][] MASTER = new String[][] {
                {"row 1"}, {"row 2"}, {"row 3"},
                {"row 6"}, {"row 7"}
            };

        rollback();
        Statement stmt = createStatement();
        try {
            stmt.executeUpdate("create table t2017 (c clob)");
        } catch (SQLException sqle) {
            assertSQLState("X0Y32", sqle);
            stmt.executeUpdate("delete from t2017");
        }
        commit();

        setAutoCommit(true);
        PreparedStatement ps = prepareStatement("insert into t2017 values (?)");
        // Insert the 3 first rows.
        for (int i=0; i < 3; i++) {
            ps.setString(1, INSERT[i]);
            assertEquals(1, ps.executeUpdate());
        }

        // Insert the 4th and 5th row with a stream that throws an IOException.
        // Partial data shouldn't be inserted into the database.

        Reader r4 = new FailingReader(518, 500);
        ps.setCharacterStream(1, r4, 518);
        try {
            ps.executeUpdate();
            fail("Insert should have failed");
        } catch (SQLException sqle) {
            // TODO: Check when exception handling has been settled.
            // The states are different between client and embedded.
            //assertSQLState(usingEmbedded() ? "XSDA4" : "XJ001", sqle);
        }

        Reader r5 = new FailingReader(67*1024, 42*1024);
        ps.setCharacterStream(1, r5, 67*1024);
        try {
            ps.executeUpdate();
            fail("Insert should have failed");
        } catch (SQLException sqle) {
            // TODO: Check when exception handling has been settled.
            // The states are different between client and embedded.
            //assertSQLState(usingEmbedded() ? "XSDA4" : "XJ001", sqle);
        }

        // The errors above should have statement severity. Insert the last two
        // rows.
        for (int i=5; i < INSERT.length; i++) {
            ps.setString(1, INSERT[i]);
            assertEquals(1, ps.executeUpdate());
        }

        // Select data in the table, compare to MASTER
        ResultSet rs = stmt.executeQuery("select * from t2017");
        JDBC.assertFullResultSet(rs, MASTER);
    }

    public void testFailedStreamInsertChar()
            throws IOException, SQLException {
        String[] INSERT = new String[] {
                "This is row 1",
                "This is row 2",
                "This is row 3",
                "This is row 4, a bit too long",
                "This is row 5, a bit too short",
                "This is row 6",
                "This is row 7",
            };
        String[][] MASTER = new String[][] {
                {"This is row 1"},
                {"This is row 2"},
                {"This is row 3"},
                //{"This is row 4, a bit too long"},
                //{"This is row 5, a bit too short"},
                {"This is row 6"},
                {"This is row 7"},
            };

        doInsertTest(INSERT, MASTER, false, false);
    }

    public void testFailedStreamInsertCharAutoCommit()
            throws IOException, SQLException {
        String[] INSERT = new String[] {
                "This is row 1",
                "This is row 2",
                "This is row 3",
                "This is row 4, a bit too long",
                "This is row 5, a bit too short",
                "This is row 6",
                "This is row 7",
            };
        String[][] MASTER = new String[][] {
                {"This is row 1"},
                {"This is row 2"},
                {"This is row 3"},
                //{"This is row 4, a bit too long"},
                //{"This is row 5, a bit too short"},
                {"This is row 6"},
                {"This is row 7"},
            };
        doInsertTest(INSERT, MASTER, true, false);
    }

    public void testFailedStreamInsertCharRollbackOnError()
            throws IOException, SQLException {
        String[] INSERT = new String[] {
                "This is row 1",
                "This is row 2",
                "This is row 3",
                "This is row 4, a bit too long",
                "This is row 5, a bit too short",
                "This is row 6",
                "This is row 7",
            };
        String[][] MASTER = new String[][] {
                //{"This is row 1"},
                //{"This is row 2"},
                //{"This is row 3"},
                //{"This is row 4, a bit too long"},
                //{"This is row 5, a bit too short"},
                {"This is row 6"},
                {"This is row 7"},
            };
        doInsertTest(INSERT, MASTER, false, true);
    }

    public void testFailedStreamInsertCharAutoCommitRollbackOnError()
            throws IOException, SQLException {
        String[] INSERT = new String[] {
                "This is row 1",
                "This is row 2",
                "This is row 3",
                "This is row 4, a bit too long",
                "This is row 5, a bit too short",
                "This is row 6",
                "This is row 7",
            };
        String[][] MASTER = new String[][] {
                {"This is row 1"},
                {"This is row 2"},
                {"This is row 3"},
                //{"This is row 4, a bit too long"},
                //{"This is row 5, a bit too short"},
                {"This is row 6"},
                {"This is row 7"},
            };
        doInsertTest(INSERT, MASTER, true, true);
    }

    public void testFailedStreamInsertBinary()
            throws IOException, SQLException {
        byte[][] INSERT = generateDefaultInsert();
        String[][] MASTER = generateMaster(INSERT, new int[] {3, 4});
        doInsertTest(INSERT, MASTER, false, false);
    }

    public void testFailedStreamInsertBinaryAutoCommit()
            throws IOException, SQLException {
        byte[][] INSERT = generateDefaultInsert();
        String[][] MASTER = generateMaster(INSERT, new int[] {3, 4});
        doInsertTest(INSERT, MASTER, true, false);
    }

    public void testFailedStreamInsertBinaryRollbackOnError()
            throws IOException, SQLException {
        byte[][] INSERT = generateDefaultInsert();
        String[][] MASTER = generateMaster(INSERT, new int[] {0, 1, 2, 3, 4});
        doInsertTest(INSERT, MASTER, false, true);
    }

    public void testFailedStreamInsertBinaryAutoCommitRollbackOnError()
            throws IOException, SQLException {
        byte[][] INSERT = generateDefaultInsert();
        String[][] MASTER = generateMaster(INSERT, new int[] {3, 4});
        doInsertTest(INSERT, MASTER, true, true);
    }

    /**
     * Performs the base test cycle; insert 3 valid rows, try to insert 2
     * invalid rows, insert 2 valid rows.
     * <p>
     * The outcome depends on whether auto-commit is on, and whether a rollback
     * is issued when an insert fails.
     *
     * @param INSERT the data to insert
     * @param MASTER the expected outcome
     * @param autoCommit the auto-commit state to use
     * @param rollbackOnError whether or not to issue a rollback if an insert
     *      fails
     *
     * @throws IOException if something goes wrong
     * @throws SQLException if something goes wrong
     */
    private void doInsertTest(String[] INSERT, String[][] MASTER,
                              boolean autoCommit, boolean rollbackOnError)
            throws IOException, SQLException {
        // A few sanity checks.
        assertEquals("Expects 7 rows", 7, INSERT.length);
        assertTrue(MASTER.length < INSERT.length);

        rollback();
        Statement stmt = createStatement();
        try {
            stmt.executeUpdate("create table t2017 (c clob)");
        } catch (SQLException sqle) {
            assertSQLState("X0Y32", sqle);
            stmt.executeUpdate("delete from t2017");
        }
        commit();

        setAutoCommit(autoCommit);
        PreparedStatement ps = prepareStatement("insert into t2017 values (?)");
        // Insert the 3 first rows.
        for (int i=0; i < 3; i++) {
            ps.setString(1, INSERT[i]);
            assertEquals(1, ps.executeUpdate());
        }

        // Insert the 4th row with a stream that's longer than the specified
        // length, then the 5th row that's shorter. Both should fail, and the
        // data shouldn't be inserted into the database.

        Reader r4 = new StringReader(INSERT[3]);
        ps.setCharacterStream(1, r4, INSERT[3].length() - 5);
        try {
            ps.executeUpdate();
            fail("Insert should have failed, stream too long");
        } catch (SQLException sqle) {
            // The states are different between client and embedded.
            assertSQLState(usingEmbedded() ? "XSDA4" : "XN015", sqle);
            if (rollbackOnError) {
                rollback();
            }
        }

        Reader r5 = new StringReader(INSERT[4]);
        ps.setCharacterStream(1, r5, INSERT[4].length() + 5);
        try {
            ps.executeUpdate();
            fail("Insert should have failed, stream too short");
        } catch (SQLException sqle) {
            // The states are different between client and embedded.
            assertSQLState(usingEmbedded() ? "XSDA4" : "XN017", sqle);
            if (rollbackOnError) {
                rollback();
            }
        }

        // The errors above should have statement severity. Insert the last
        // two rows and make sure the transaction commits.
        for (int i=5; i < INSERT.length; i++) {
            ps.setString(1, INSERT[i]);
            assertEquals(1, ps.executeUpdate());
        }

        if (!autoCommit) {
            commit();
        }

        // Select data in the table, compare to MASTER
        ResultSet rs = stmt.executeQuery("select * from t2017");
        JDBC.assertFullResultSet(rs, MASTER);
    }

    /**
     * Performs the base test cycle; insert 3 valid rows, try to insert 2
     * invalid rows, insert 2 valid rows.
     * <p>
     * The outcome depends on whether auto-commit is on, and whether a rollback
     * is issued when an insert fails.
     *
     * @param INSERT the data to insert
     * @param autoCommit the auto-commit state to use
     * @param rollbackOnError whether or not to issue a rollback if an insert
     *      fails
     *
     * @throws IOException if something goes wrong
     * @throws SQLException if something goes wrong
     */
    private void doInsertTest(int[] INSERT,
                              boolean autoCommit, boolean rollbackOnError)
            throws IOException, SQLException {
        // A few sanity checks.
        assertEquals("Expects 7 rows", 7, INSERT.length);

        rollback();
        Statement stmt = createStatement();
        try {
            stmt.executeUpdate("create table t2017_id (id int unique, c clob)");
        } catch (SQLException sqle) {
            assertSQLState("X0Y32", sqle);
            stmt.executeUpdate("delete from t2017_id");
        }
        commit();

        setAutoCommit(autoCommit);
        PreparedStatement ps =
                prepareStatement("insert into t2017_id values (?, ?)");
        // Insert the 3 first rows (id is 1-based).
        for (int i=0; i < 3; i++) {
            ps.setInt(1, i+1);
            int length = INSERT[i];
            ps.setCharacterStream(2, new LoopingAlphabetReader(length), length);
            assertEquals(1, ps.executeUpdate());
        }

        // Insert the 4th row with a stream that's longer than the specified
        // length, then the 5th row that's shorter. Both should fail, and the
        // data shouldn't be inserted into the database.

        Reader r4 = new LoopingAlphabetReader(INSERT[3]);
        ps.setInt(1, 4);
        ps.setCharacterStream(2, r4, INSERT[3] - 5);
        try {
            ps.executeUpdate();
            fail("Insert should have failed, stream too long");
        } catch (SQLException sqle) {
            // The states are different between client and embedded.
            assertSQLState(usingEmbedded() ? "XSDA4" : "XN015", sqle);
            if (rollbackOnError) {
                rollback();
            }
        }

        Reader r5 = new LoopingAlphabetReader(INSERT[4]);
        ps.setInt(1, 5);
        ps.setCharacterStream(2, r5, INSERT[4] + 5);
        try {
            ps.executeUpdate();
            fail("Insert should have failed, stream too short");
        } catch (SQLException sqle) {
            // The states are different between client and embedded.
            assertSQLState(usingEmbedded() ? "XSDA4" : "XN017", sqle);
            if (rollbackOnError) {
                rollback();
            }
        }

        // The errors above should have statement severity. Insert the last
        // two rows and make sure the transaction commits.
        for (int i=5; i < INSERT.length; i++) {
            ps.setInt(1, i+1);
            int length = INSERT[i];
            ps.setCharacterStream(2, new LoopingAlphabetReader(length), length);
            assertEquals(1, ps.executeUpdate());
        }

        if (!autoCommit) {
            commit();
        }

        // Make sure we have the expected number of rows.
        ResultSet rs = stmt.executeQuery("select count(*) from t2017_id");
        rs.next();
        assertEquals((rollbackOnError && !autoCommit ? 2 : 5), rs.getInt(1));

        // Select data in the table, compare to what we expect.
        rs = stmt.executeQuery( "select * from t2017_id order by id asc");
        // Check rows 1-4 if rollback on error is false.
        if (autoCommit || !rollbackOnError) {
            for (int i=0; i < 3; i++) {
                rs.next();
                int id = rs.getInt(1);
                assertTrue(id - 1 == i);
                assertEquals(new LoopingAlphabetReader(INSERT[i]),
                             rs.getCharacterStream(2));
            }
        }
        // Check rows 6 and 7.
        for (int i=5; i < 7; i++) {
            rs.next();
            int id = rs.getInt(1);
            assertTrue(id - 1 == i);
            assertEquals(new LoopingAlphabetReader(INSERT[i]),
                         rs.getCharacterStream(2));
        }
        assertFalse(rs.next());
        rs.close();
    }

    /**
     * Performs the base test cycle; insert 3 valid rows, try to insert 2
     * invalid rows, insert 2 valid rows.
     * <p>
     * The outcome depends on whether auto-commit is on, and whether a rollback
     * is issued when an insert fails.
     *
     * @param INSERT the data to insert
     * @param MASTER the expected outcome
     * @param autoCommit the auto-commit state to use
     * @param rollbackOnError whether or not to issue a rollback if an insert
     *      fails
     *
     * @throws IOException if something goes wrong
     * @throws SQLException if something goes wrong
     */
    private void doInsertTest(byte[][] INSERT, String[][] MASTER,
                              boolean autoCommit, boolean rollbackOnError)
            throws IOException, SQLException {
        // A few sanity checks.
        assertEquals("Expects 7 rows", 7, INSERT.length);
        assertTrue(MASTER.length < INSERT.length);

        rollback();
        Statement stmt = createStatement();
        try {
            stmt.executeUpdate("create table t2017_binary (b blob)");
        } catch (SQLException sqle) {
            assertSQLState("X0Y32", sqle);
            stmt.executeUpdate("delete from t2017_binary");
        }
        commit();

        setAutoCommit(autoCommit);
        PreparedStatement ps = prepareStatement(
                "insert into t2017_binary values (?)");
        // Insert the 3 first rows.
        for (int i=0; i < 3; i++) {
            ps.setBytes(1, INSERT[i]);
            assertEquals(1, ps.executeUpdate());
        }

        // Insert the 4th row with a stream that's longer than the specified
        // length, then the 5th row that's shorter. Both should fail, and the
        // data shouldn't be inserted into the database.

        InputStream r4 = new ByteArrayInputStream(INSERT[3]);
        ps.setBinaryStream(1, r4, INSERT[3].length - 5);
        try {
            ps.executeUpdate();
            fail("Insert should have failed, stream too long");
        } catch (SQLException sqle) {
            // The states are different between client and embedded.
            assertSQLState(usingEmbedded() ? "XSDA4" : "XN015", sqle);
            if (rollbackOnError) {
                rollback();
            }
        }

        InputStream r5 = new ByteArrayInputStream(INSERT[4]);
        ps.setBinaryStream(1, r5, INSERT[4].length + 5);
        try {
            ps.executeUpdate();
            fail("Insert should have failed, stream too short");
        } catch (SQLException sqle) {
            // The states are different between client and embedded.
            assertSQLState(usingEmbedded() ? "XSDA4" : "XN017", sqle);
            if (rollbackOnError) {
                rollback();
            }
        }

        // The errors above should have statement severity. Insert the last
        // two rows and make sure the transaction commits.
        for (int i=5; i < INSERT.length; i++) {
            ps.setBytes(1, INSERT[i]);
            assertEquals(1, ps.executeUpdate());
        }

        if (!autoCommit) {
            commit();
        }

        // Select data in the table, compare to MASTER
        ResultSet rs = stmt.executeQuery("select * from t2017_binary");
        JDBC.assertFullResultSet(rs, MASTER);
    }

    /**
     * WARNING: This reader is not a general purpose reader!!!
     * <p>
     * Reader thrown an exception when a certain amount of characters has been
     * returned (or is about to be returned).
     */
    public static class FailingReader
            extends Reader {

        private final LoopingAlphabetReader in;
        private final long failAtPos;
        private long pos;

        /**
         * Creates a new failing reader.
         *
         * @param length the total length of the source
         * @param failAtPos the position to fail at (specifying zero or a
         *      negative value causes an exception on the first read request)
         */
        public FailingReader(long length, long failAtPos) {
            this.failAtPos = failAtPos;
            this.in = new LoopingAlphabetReader(length);
        }

        public int read()
                throws IOException {
            // If we failed once, just keep failing on subsequent requests.
            pos++;
            int ret = in.read();
            if (pos >= failAtPos) {
                throw new IOException("forced exception");
            }
            return ret;
        }

        public int read(char[] cbuf, int off, int len)
                throws IOException {
            // If we failed once, just keep failing on subsequent requests.
            // Try to return some valid data before failing.
            if (pos == 0 && failAtPos > 1) {
                len = (int)Math.min(failAtPos -1, len);
            }
            int ret = in.read(cbuf, off, len);
            if (ret != -1) {
                pos += ret;
            }
            if (pos >= failAtPos) {
                throw new IOException("forced exception");
            }
            return ret;
        }

        public void close() {
            in.close();
        }
    }

    /**
     * Helper method returning the default bytes used for testing binary data.
     *
     * @return A byte array with byte arrays ("rows").
     */
    public static byte[][] generateDefaultInsert() {
        try {
            byte[][] INSERT = new byte[][] {
                "This is row 1".getBytes(UTF8),
                "This is row 2".getBytes(UTF8),
                "This is row 3".getBytes(UTF8),
                "This is row 4, a bit too long".getBytes(UTF8),
                "This is row 5, a bit too short".getBytes(UTF8),
                "This is row 6".getBytes(UTF8),
                "This is row 7".getBytes(UTF8),
            };
            return INSERT;
        } catch (UnsupportedEncodingException uuee) {
            // Just return null, should never happen if UTF-8 is used.
            return null;
        }
    }

    /**
     * Helper method returning a string array with the expected values from the
     * database (based on the values inserted).
     * <p>
     * The purpose of this method is to convert from byte[] to String (as
     * done by {@code ResultSet.getString()} when invoked on a column with
     * binary data).
     *
     * @param insert the data inserted
     * @param excludes the rows that is expected to fail, will be ignored
     * @return A string array with expected strings.
     */
    public static String[][] generateMaster(byte[][] insert, int[] excludes) {
        Arrays.sort(excludes);
        int exIx = 0;
        String[][] res = new String[insert.length - excludes.length][];
        int resIx = 0;
        for (int i=0; i < insert.length; i++) {
            if (i == excludes[exIx]) {
                if (exIx < excludes.length -1) {
                    exIx++;
                }
                continue;
            }
            String str = new BigInteger(1, insert[i]).toString(16);
            // Pad if there are missing nulls.
            while (str.length() < insert[i].length *2) {
                str = "0" + str;
            }
            res[resIx++] = new String[] {str};
        }
        return res;
    }
}
