/*
 * 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.brooklyn.entity.database.mysql;

import org.apache.brooklyn.core.effector.EffectorBody;
import org.apache.brooklyn.core.location.Locations;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.brooklyn.feed.ssh.SshFeed;
import org.apache.brooklyn.feed.ssh.SshPollConfig;
import org.apache.brooklyn.feed.ssh.SshPollValue;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.text.Identifiers;
import org.apache.brooklyn.util.text.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Function;

public class MySqlNodeImpl extends SoftwareProcessImpl implements MySqlNode {

    private static final Logger LOG = LoggerFactory.getLogger(MySqlNodeImpl.class);

    /** This comes from mysql.cnf
     * See http://dev.mysql.com/doc/refman/5.6/en/mysql-install-db.html and http://dev.mysql.com/doc/refman/5.7/en/mysql-install-db.html
     * for more details.
     * */
    String DEFAULT_USERNAME = "root";

    private SshFeed feed;

    @Override
    public Class<?> getDriverInterface() {
        return MySqlDriver.class;
    }

    @Override
    public MySqlDriver getDriver() {
        return (MySqlDriver) super.getDriver();
    }

    @Override
    public void init() {
        super.init();
        getMutableEntityType().addEffector(EXECUTE_SCRIPT, new EffectorBody<String>() {
            @Override
            public String call(ConfigBag parameters) {
                return executeScript((String)parameters.getStringKey("commands"));
            }
        });
        getMutableEntityType().addEffector(MySqlNodeEffectors.EXPORT_DUMP);
        getMutableEntityType().addEffector(MySqlNodeEffectors.IMPORT_DUMP);
        getMutableEntityType().addEffector(MySqlNodeEffectors.CHANGE_PASSWORD);
    }

    @Override
    protected void connectSensors() {
        super.connectSensors();
        sensors().set(DATASTORE_URL, String.format("mysql://%s:%s/", getAttribute(HOSTNAME), getAttribute(MYSQL_PORT)));
        sensors().set(USER, getUser());
        /*
         * TODO status gives us things like:
         *   Uptime: 2427  Threads: 1  Questions: 581  Slow queries: 0  Opens: 53  Flush tables: 1  Open tables: 35  Queries per second avg: 0.239
         * So can extract lots of sensors from that.
         */
        Maybe<SshMachineLocation> machine = Locations.findUniqueSshMachineLocation(getLocations());
        boolean retrieveUsageMetrics = getConfig(RETRIEVE_USAGE_METRICS);

        if (machine.isPresent()) {
            String cmd = getDriver().getStatusCmd();
            feed = SshFeed.builder()
                    .entity(this)
                    .period(config().get(SERVICE_PROCESS_IS_RUNNING_POLL_PERIOD))
                    .machine(machine.get())
                    .poll(new SshPollConfig<Double>(QUERIES_PER_SECOND_FROM_MYSQL)
                            .command(cmd)
                            .onSuccess(new Function<SshPollValue, Double>() {
                                @Override
                                public Double apply(SshPollValue input) {
                                    String q = Strings.getFirstWordAfter(input.getStdout(), "Queries per second avg:");
                                    if (q==null) return null;
                                    return Double.parseDouble(q);
                                }})
                            .setOnFailureOrException(null)
                            .enabled(retrieveUsageMetrics))
                    .poll(new SshPollConfig<Boolean>(SERVICE_PROCESS_IS_RUNNING)
                            .command(cmd)
                            .setOnSuccess(true)
                            .setOnFailureOrException(false)
                            .suppressDuplicates(true))
                    .build();
        } else {
            LOG.warn("Location(s) {} not an ssh-machine location, so not polling for status; setting serviceUp immediately", getLocations());
            sensors().set(SERVICE_UP, true);
        }
    }

    @Override
    protected void disconnectSensors() {
        if (feed != null) feed.stop();
        super.disconnectSensors();
    }

    public int getPort() {
        return getAttribute(MYSQL_PORT);
    }

    public synchronized String getSocketUid() {
        String result = getAttribute(MySqlNode.SOCKET_UID);
        if (Strings.isBlank(result)) {
            result = Identifiers.makeRandomId(6);
            sensors().set(MySqlNode.SOCKET_UID, result);
        }
        return result;
    }

    public String getUser() {
        return DEFAULT_USERNAME;
    }

    public String getPassword() {
        String result = getAttribute(MySqlNode.PASSWORD);
        if (Strings.isBlank(result)) {
            result = Identifiers.makeRandomId(12);
            sensors().set(MySqlNode.PASSWORD, result);
        }
        return result;
    }

    @Override
    public String getShortName() {
        return "MySQL";
    }

    @Override
    public String executeScript(String commands) {
        return getDriver().executeScriptAsync(commands).block().getStdout();
    }

}
