/*
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.edgent.test.connectors.mqtt;

import static org.junit.Assume.assumeTrue;

import java.net.Socket;
import java.net.URI;
import java.util.UUID;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.rules.TestName;

/**
 * Uses the MQTT test broker at: tcp://test.mosquitto.org:1883
 * 
 * See <a href="http://test.mosquitto.org/">http://test.mosquitto.org/</a>
 * 
 * The tests are skipped if unable to connect (e.g., due to firewall config,
 * or the public broker not available for whatever reason).
 */
// TODO fix this test
@Ignore
public class MqttOpenTest extends MqttStreamsTestManual {
    private String uniqueid = UUID.randomUUID().toString().replace('-','_');
    
    @Rule public TestName name = new TestName();
    
    @Before
    public void setupAuthInfo() {
        this.authInfo.clear();  // mosquitto.org server isn't happy w/username&pw
        // Skip tests if the MQTT server can't be contacted.
        try {
            URI uri = new URI(getServerURI());
            Socket s = new Socket(uri.getHost(), uri.getPort());
            s.close();
        } catch (Exception e) {
            System.err.println("Skipping "+name.getMethodName()+": Unable to connect to MQTT broker "+getServerURI()+" : "+e.getMessage());
            // e.printStackTrace();
            assumeTrue(false);
        }
    }
    
    boolean isSslConnectionOK() {
      try {
          URI uri = new URI(getSslServerURI());
          Socket s = new Socket(uri.getHost(), uri.getPort());
          s.close();
          return true;
      } catch (Exception e) {
          System.err.println(name.getMethodName()+": Unable to connect to MQTT broker "+getSslServerURI()+" : "+e.getMessage());
          // e.printStackTrace();
          return false;
      }
    }
    
    protected String[] getMqttTopics() {
        String[] topics = super.getMqttTopics();
        for (int i =0 ; i < topics.length; i++) {
            topics[i] = uniqueid + "/" + topics[i];
        }
        return topics;
    }
    
    protected String getServerURI() {
//        return "tcp://test.mosquitto.org:1883";  // EDGENT-408
        return "tcp://iot.eclipse.org:1883";
    }
    
    protected String getSslServerURI() {
//        return "ssl://test.mosquitto.org:8883";  // EDGENT-408
        return "ssl://iot.eclipse.org:8883";
    }
    
    protected String getSslClientAuthServerURI() {
        return "ssl://test.mosquitto.org:8884";
    }
    
    protected String newClientId(String name) {
        return uniqueid + "_" + name;
    }
    
    @Ignore
    public void testIdleSubscribe() {}  // intermittent (timing related?) failures
    @Ignore
    public void testIdlePublish() {}  // intermittent (timing related?) failures
    @Ignore
    public void testSslClientAuth() {} // we don't have a mosquitto.org generated client cert
    
    public void testSsl() {
      if (!isSslConnectionOK()) {
        System.err.println("Skipping testSsl()");
        assumeTrue(false);
      }
    }

}
