//@ {VER(>=8.0.11)}

//@<> INCLUDE async_utils.inc

//@<> Setup

var uuid1 = "5ef81566-9395-11e9-87e9-111111111111";
var uuid2 = "5ef81566-9395-11e9-87e9-222222222222";
var id1 = 11;
var id2 = 22;
testutil.deploySandbox(__mysql_sandbox_port1, "root", {server_uuid: uuid1, server_id: id1});
testutil.deploySandbox(__mysql_sandbox_port2, "root", {server_uuid: uuid2, server_id: id2});

var s1 = mysql.getSession(__sandbox_uri1);
var s2 = mysql.getSession(__sandbox_uri2);

//=========
// Metadata schema already exists, but it's an old version

//@<> create replicaset (should fail)
shell.connect(__sandbox_uri1);
session.runSql("CREATE SCHEMA mysql_innodb_cluster_metadata");
testutil.importData(__sandbox_uri1, __dba_data_path + "/md-1.0.1-cluster_1member.sql");

EXPECT_THROWS(function(){
    dba.createReplicaSet("myrs");
}, "Metadata version is not compatible");
EXPECT_OUTPUT_CONTAINS(`Incompatible Metadata version. This operation is disallowed because the installed Metadata version '1.0.1' is lower than the required version, '${testutil.getCurrentMetadataVersion()}'. Upgrade the Metadata to remove this restriction. See \\? dba.upgradeMetadata for additional details.`);

// Operation not allowed. The installed metadata version 1.0.1 is lower than the version required by Shell which is version 2.2.0. Upgrade the metadata to execute this operation. See \? dba.upgradeMetadata for additional details. (RuntimeError)

// ========
// Should NOT be possible to store metadata from different clusters and replicasets
// in the same schema

//@<> Merge schema from different sources (cluster then rs)
reset_instance(s1);
reset_instance(s2);
shell.connect(__sandbox_uri1);
var cl= dba.createCluster("mycluster");
cluster_id1 = s1.runSql("SELECT cluster_id FROM mysql_innodb_cluster_metadata.clusters WHERE cluster_name='mycluster'").fetchOne()[0];

// this will replicate the MD schema from the cluster to sb2
setup_slave(s2, __mysql_sandbox_port1, "mychannel");
testutil.waitMemberTransactions(__mysql_sandbox_port2, __mysql_sandbox_port1);

// stop the channel, since unmanaged channels are not allowed right now
s2.runSql("STOP " + get_replica_keyword() + " FOR CHANNEL 'mychannel'");
s2.runSql("RESET " + get_replica_keyword() + " ALL FOR CHANNEL 'mychannel'");

// this should now create the replicaset, overwriting the existing cluster metadata
shell.connect(__sandbox_uri2);
var rs= dba.createReplicaSet("myrs");
cluster_id2 = s2.runSql("SELECT cluster_id FROM mysql_innodb_cluster_metadata.clusters WHERE cluster_name='myrs'").fetchOne()[0];

// make sure there are no replication conflicts generated by the MD schema
shell.dumpRows(s1.runSql("SHOW "+__replica_keyword_capital+" STATUS"), "vertical");

//@ clusters
shell.dumpRows(s1.runSql("SELECT * FROM mysql_innodb_cluster_metadata.v2_clusters"), "vertical");

//@ instances
shell.dumpRows(s1.runSql("SELECT * FROM mysql_innodb_cluster_metadata.v2_instances"), "vertical");

//@ this_instance
shell.dumpRows(s1.runSql("SELECT * FROM mysql_innodb_cluster_metadata.v2_this_instance"), "tabbed");
shell.dumpRows(s2.runSql("SELECT * FROM mysql_innodb_cluster_metadata.v2_this_instance"), "tabbed");

//@ Check sb1.getCluster()
shell.connect(__sandbox_uri1);
c = dba.getCluster();
c.status();

//@ Check sb1.getReplicaSet() (should fail)
dba.getReplicaSet();

//@ Check sb2.getCluster() (should fail)
shell.connect(__sandbox_uri2);
dba.getCluster();

//@ Check sb2.getReplicaSet()
r = dba.getReplicaSet();
r.status({extended:1});

//@<> Cleanup everything
s1.runSql("STOP group_replication");
s1.runSql("SET GLOBAL group_replication_local_address=NULL");
reset_instance(s1);
reset_instance(s2);

// ===== Repeat everything starting with a replicaset
//@ Merge schema from different sources (rs then cluster)

shell.connect(__sandbox_uri1);
var cl= dba.createReplicaSet("myrs");
cluster_id1 = s1.runSql("SELECT cluster_id FROM mysql_innodb_cluster_metadata.clusters WHERE cluster_name='myrs'").fetchOne()[0];

// this will replicate the MD schema from the cluster to sb2
setup_slave(s2, __mysql_sandbox_port1, "mychannel");
testutil.waitMemberTransactions(__mysql_sandbox_port2, __mysql_sandbox_port1);

// stop the channel, since unmanaged channels are not allowed right now
s2.runSql("STOP " + get_replica_keyword() + " FOR CHANNEL 'mychannel'");
s2.runSql("RESET " + get_replica_keyword() + " ALL FOR CHANNEL 'mychannel'");

// this should now create the replicaset in the same schema as the cluster, overwriting it
shell.connect(__sandbox_uri2);
var rs= dba.createCluster("mycluster");
cluster_id2 = s2.runSql("SELECT cluster_id FROM mysql_innodb_cluster_metadata.clusters WHERE cluster_name='mycluster'").fetchOne()[0];

// make sure there are no replication conflicts generated by the MD schema
shell.dumpRows(s1.runSql("SHOW " + get_replica_keyword() + " STATUS"), "vertical");

shell.dumpRows(s1.runSql("SELECT * FROM mysql_innodb_cluster_metadata.v2_clusters"), "tabbed");
shell.dumpRows(s1.runSql("SELECT * FROM mysql_innodb_cluster_metadata.v2_instances"), "tabbed");

//@ this_instance again
shell.dumpRows(s1.runSql("SELECT * FROM mysql_innodb_cluster_metadata.v2_this_instance"), "tabbed");
shell.dumpRows(s2.runSql("SELECT * FROM mysql_innodb_cluster_metadata.v2_this_instance"), "tabbed");

//@ Check sb1.getCluster() (should fail)
shell.connect(__sandbox_uri1);
dba.getCluster();

//@ Check sb1.getReplicaSet()
r = dba.getReplicaSet();
r.status();

//@ Check sb2.getCluster()
shell.connect(__sandbox_uri2);
c = dba.getCluster();
c.status();

//@ Check sb2.getReplicaSet() (should fail)
dba.getReplicaSet();

//@<> Cleanup everything again
s2.runSql("STOP group_replication");
reset_instance(s1);
reset_instance(s2);

//@<> Cleanup
testutil.destroySandbox(__mysql_sandbox_port1);
testutil.destroySandbox(__mysql_sandbox_port2);
